*** empty log message ***
diff --git a/bundles/org.eclipse.team.cvs.ui/.classpath b/bundles/org.eclipse.team.cvs.ui/.classpath
index 07afd19..f475763 100644
--- a/bundles/org.eclipse.team.cvs.ui/.classpath
+++ b/bundles/org.eclipse.team.cvs.ui/.classpath
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-    <classpathentry kind="src" path="src/"/>
+    <classpathentry kind="src" path="src"/>
     <classpathentry kind="src" path="/org.apache.xerces"/>
     <classpathentry kind="src" path="/org.eclipse.core.runtime"/>
     <classpathentry kind="src" path="/org.eclipse.core.resources"/>
     <classpathentry kind="src" path="/org.eclipse.ui"/>
     <classpathentry kind="src" path="/org.eclipse.team.core"/>
     <classpathentry kind="src" path="/org.eclipse.team.ui"/>
+    <classpathentry kind="src" path="/org.eclipse.team.cvs.core"/>
     <classpathentry kind="src" path="/org.eclipse.compare"/>
     <classpathentry kind="src" path="/org.eclipse.core.boot"/>
     <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-    <classpathentry kind="src" path="/org.eclipse.team.cvs.core"/>
     <classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/bundles/org.eclipse.team.cvs.ui/plugin.properties b/bundles/org.eclipse.team.cvs.ui/plugin.properties
index b23ea56..d471dc3 100644
--- a/bundles/org.eclipse.team.cvs.ui/plugin.properties
+++ b/bundles/org.eclipse.team.cvs.ui/plugin.properties
@@ -188,4 +188,4 @@
 CVSWorkspaceSubscriber.merge.tooltip=Perform an update merge on the visible resources
 
 WorkInProgress.name=Work In Progress
-CVSRemoteQuickDiffProvider=CVS Remote Revision
\ No newline at end of file
+CVSRemoteQuickDiffProvider.label=Latest CVS Revision
\ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.ui/plugin.xml b/bundles/org.eclipse.team.cvs.ui/plugin.xml
index ecb4378..e4d6a5a 100644
--- a/bundles/org.eclipse.team.cvs.ui/plugin.xml
+++ b/bundles/org.eclipse.team.cvs.ui/plugin.xml
@@ -885,7 +885,7 @@
 	
 	<!-- ********** QuickDiff text editor support ************** -->
 	<extension
-         point="org.eclipse.ui.editors.quickDiffReferenceProvider">
+         point="org.eclipse.ui.workbench.texteditor.quickDiffReferenceProvider">
       <referenceprovider
             label="%CVSRemoteQuickDiffProvider.label"
             class="org.eclipse.team.internal.ccvs.ui.RemoteRevisionQuickDiffProvider"
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java
index aabc680..8917530 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java
@@ -16,6 +16,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 
+import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
@@ -143,8 +144,13 @@
 
 		setTitle(Policy.bind("CVSAnnotateView.showFileAnnotation", new Object[] {cvsResource.getName()})); //$NON-NLS-1$
 		try {
-			setTitleToolTip(cvsResource.getIResource().getFullPath().toString());
-		} catch (CVSException e1) {
+			IResource localResource = cvsResource.getIResource();
+			if (localResource != null) {
+				setTitleToolTip(localResource.getFullPath().toString());
+			} else {
+				setTitleToolTip(cvsResource.getName());
+			}
+		} catch (CVSException e) {
 			setTitleToolTip(cvsResource.getName());
 		}
 		
@@ -272,7 +278,9 @@
 		
 		
 		// Select the revision in the history view.
-		historyView.selectRevision(listSelection.getRevision());
+		if(historyView != null) {
+			historyView.selectRevision(listSelection.getRevision());
+		}
 		lastSelectionWasText = false;			
 	}
 
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSAbstractResolutionGenerator.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSAbstractResolutionGenerator.java
deleted file mode 100644
index e94795f..0000000
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSAbstractResolutionGenerator.java
+++ /dev/null
@@ -1,70 +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.ui;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IMarkerResolutionGenerator;
-import org.eclipse.ui.IWorkbenchWindow;
-
-public abstract class CVSAbstractResolutionGenerator implements IMarkerResolutionGenerator {
-	protected void run(final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
-		final Exception[] exception = new Exception[] {null};
-		Display.getDefault().syncExec(new Runnable() {
-			public void run() {
-				try {
-					Shell shell;
-					IWorkbenchWindow window = CVSUIPlugin.getPlugin().getWorkbench().getActiveWorkbenchWindow();
-					boolean disposeShell = false;
-					if (window != null) {
-						shell = window.getShell();
-					} else {
-						Display display = Display.getCurrent();
-						shell = new Shell(display);
-						disposeShell = true;
-					}
-					new ProgressMonitorDialog(shell).run(true, true, runnable);
-					if (disposeShell) shell.dispose();
-				} catch (InterruptedException e) {
-					exception[0] = e;
-				} catch (InvocationTargetException e) {
-					exception[0] = e;
-				}
-			}
-		});
-		if (exception[0] != null) {
-			if (exception[0] instanceof InvocationTargetException) {
-				throw (InvocationTargetException)exception[0];
-			} else if (exception[0] instanceof InterruptedException) {
-				throw (InterruptedException)exception[0];
-			} else {
-				throw new InvocationTargetException(exception[0]);
-			}
-		}
-	}
-	
-	/**
-	 * Shows the given errors to the user.
-	 * 
-	 * @param status  the status containing the error
-	 * @param title  the title of the error dialog
-	 * @param message  the message for the error dialog
-	 * @param shell  the shell to open the error dialog in
-	 */
-	protected void handle(Throwable exception, String title, final String message) {
-		CVSUIPlugin.openError(null, title, message, exception, CVSUIPlugin.LOG_NONTEAM_EXCEPTIONS);
-	}
-}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSAddResolutionGenerator.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSAddResolutionGenerator.java
deleted file mode 100644
index dbad4b8..0000000
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSAddResolutionGenerator.java
+++ /dev/null
@@ -1,134 +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.ui;
- 
-import java.lang.reflect.InvocationTargetException;
-
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-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.CVSTeamProvider;
-import org.eclipse.team.internal.ccvs.core.ICVSResource;
-import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
-import org.eclipse.ui.IMarkerResolution;
-
-/**
- * Generate marker resoultions for a cvs remove marker
- */
-public class CVSAddResolutionGenerator extends CVSAbstractResolutionGenerator {
-	/*
-	 * @see IMarkerResolutionGenerator#getResolutions(IMarker)
-	 */
-	public IMarkerResolution[] getResolutions(IMarker marker) {
-		IMarkerResolution manage = new IMarkerResolution() {
-			public String getLabel() {
-				return Policy.bind("CVSAddResolutionGenerator.Add_Resource_to_CVS_1"); //$NON-NLS-1$
-			}
-			public void run(IMarker marker) {
-				try {
-					final IResource resource = marker.getResource();
-					ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
-					final TeamException[] exception = new TeamException[] {null};
-					if ( ! cvsResource.isManaged()) {
-						CVSAddResolutionGenerator.this.run(new IRunnableWithProgress() {
-							public void run(IProgressMonitor monitor)throws InvocationTargetException, InterruptedException {
-								try {
-									((CVSTeamProvider)RepositoryProvider.getProvider(resource.getProject())).add(new IResource[] {resource}, IResource.DEPTH_ZERO, monitor);
-								} catch (TeamException e) {
-									exception[0] = e;
-								}
-							}
-						});
-					}
-					if (exception[0] != null) {
-						throw exception[0];
-					}
-					marker.delete();
-				} catch (TeamException e) {
-					handle(e, null, null);
-				} catch (CoreException e) {
-					handle(e, null, null);
-				} catch (InvocationTargetException e) {
-					handle(e, null, null);
-				}  catch (InterruptedException e) {
-					// do nothing
-				}
-			}
-		};
-		IMarkerResolution manageDeep = new IMarkerResolution() {
-			public String getLabel() {
-				return Policy.bind("CVSAddResolutionGenerator.Add_Resource_and_Children_to_CVS_2"); //$NON-NLS-1$
-			}
-			public void run(IMarker marker) {
-				try {
-					final IResource resource = marker.getResource();
-					ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
-					final TeamException[] exception = new TeamException[] {null};
-					if ( ! cvsResource.isManaged()) {
-						CVSAddResolutionGenerator.this.run(new IRunnableWithProgress() {
-							public void run(IProgressMonitor monitor)throws InvocationTargetException, InterruptedException {
-								try {
-									((CVSTeamProvider)RepositoryProvider.getProvider(resource.getProject())).add(new IResource[] {resource}, IResource.DEPTH_INFINITE, monitor);
-								} catch (TeamException e) {
-									exception[0] = e;
-								}
-							}
-						});
-					}
-					if (exception[0] != null) {
-						throw exception[0];
-					}
-					marker.delete();
-				} catch (TeamException e) {
-					handle(e, null, null);
-				} catch (CoreException e) {
-					handle(e, null, null);
-				} catch (InvocationTargetException e) {
-					handle(e, null, null);
-				}  catch (InterruptedException e) {
-					// do nothing
-				}
-			}
-
-		};
-		IMarkerResolution ignore =  new IMarkerResolution() {
-			public String getLabel() {
-				return Policy.bind("CVSAddResolutionGenerator.Add_to_.cvsignore_3"); //$NON-NLS-1$
-			}
-			public void run(IMarker marker) {
-				try {
-					ICVSResource resource = CVSWorkspaceRoot.getCVSResourceFor(marker.getResource());
-					if ( resource.isManaged()) {
-						resource.unmanage(null);
-					}
-					resource.setIgnored();
-					marker.delete();
-				} catch (CVSException e) {
-					handle(e, null, null);
-				} catch (CoreException e) {
-					handle(e, null, null);
-				}
-			}
-
-		};
-		if (marker.getResource().getType() == IResource.FILE) {
-			return new IMarkerResolution[] {manage, ignore};
-		} else {
-			return new IMarkerResolution[] {manageDeep, manage, ignore};
-		}
-	}
-}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java
index 777db2a..a63e83b 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java
@@ -95,7 +95,7 @@
 	public CVSLightweightDecorator() {
 		CVSProviderPlugin.addResourceStateChangeListener(this);
 		CVSProviderPlugin.broadcastDecoratorEnablementChanged(true /* enabled */);
-		exceptions = new ExceptionCollector(Policy.bind("CVSDecorator.exceptionMessage"), CVSUIPlugin.ID, IStatus.ERROR, CVSUIPlugin.getPlugin().getLog());
+		exceptions = new ExceptionCollector(Policy.bind("CVSDecorator.exceptionMessage"), CVSUIPlugin.ID, IStatus.ERROR, CVSUIPlugin.getPlugin().getLog()); //$NON-NLS-1$
 	}
 
 	public static boolean isDirty(final ICVSResource cvsResource) {
@@ -398,7 +398,8 @@
 				// check if the folder is local diectory with no remote
 				ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)resource);
 				try {
-					if (cvsFolder.getFolderSyncInfo().getRepository().equals(FolderSyncInfo.VIRTUAL_DIRECTORY)) {
+					FolderSyncInfo folderSyncInfo = cvsFolder.getFolderSyncInfo();
+					if (folderSyncInfo != null && folderSyncInfo.getRepository().equals(FolderSyncInfo.VIRTUAL_DIRECTORY)) {
 						return noRemoteDir;
 					}
 				} catch (CVSException e) {
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java
index b589847..bcd0593 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java
@@ -251,9 +251,9 @@
 					try {
 						Utils.runWithProgress(parent, cancelable, runnable);
 					} catch (InvocationTargetException e) {
-						exception[1] = e;
+						exception[0] = e;
 					} catch (InterruptedException e) {
-						exception[1] = e;
+						exception[0] = e;
 					}
 				}
 			};
@@ -342,6 +342,8 @@
 		createImageDescriptor(ICVSUIConstants.IMG_REFRESH, baseURL);
 		createImageDescriptor(ICVSUIConstants.IMG_REFRESH_ENABLED, baseURL);
 		createImageDescriptor(ICVSUIConstants.IMG_REFRESH_DISABLED, baseURL);
+		createImageDescriptor(ICVSUIConstants.IMG_LINK_WITH_EDITOR, baseURL);
+		createImageDescriptor(ICVSUIConstants.IMG_LINK_WITH_EDITOR_ENABLED, baseURL);
 		createImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL, baseURL);
 		createImageDescriptor(ICVSUIConstants.IMG_COLLAPSE_ALL_ENABLED, baseURL);
 		createImageDescriptor(ICVSUIConstants.IMG_NEWLOCATION, baseURL);
@@ -558,14 +560,15 @@
 		Preferences corePrefs = CVSProviderPlugin.getPlugin().getPluginPreferences();
 		
 		// work in progress START
-		store.setDefault(ICVSUIConstants.BACKGROUND_REPOVIEW, false);
-		store.setDefault(ICVSUIConstants.BACKGROUND_OPERATIONS, false);
-		store.setDefault(ICVSUIConstants.USE_NEW_SYNCVIEW, false);
+		store.setDefault(ICVSUIConstants.BACKGROUND_REPOVIEW, true);
+		store.setDefault(ICVSUIConstants.BACKGROUND_OPERATIONS, true);
+		store.setDefault(ICVSUIConstants.USE_NEW_SYNCVIEW, true);
 		// work in progress END
 		
 		store.setDefault(ICVSUIConstants.PREF_REPOSITORIES_ARE_BINARY, false);
 		store.setDefault(ICVSUIConstants.PREF_SHOW_COMMENTS, true);
 		store.setDefault(ICVSUIConstants.PREF_SHOW_TAGS, true);
+		store.setDefault(ICVSUIConstants.PREF_HISTORY_VIEW_EDITOR_LINKING, false);
 		store.setDefault(ICVSUIConstants.PREF_PRUNE_EMPTY_DIRECTORIES, CVSProviderPlugin.DEFAULT_PRUNE);
 		store.setDefault(ICVSUIConstants.PREF_TIMEOUT, CVSProviderPlugin.DEFAULT_TIMEOUT);
 		store.setDefault(ICVSUIConstants.PREF_CONSIDER_CONTENTS, false);
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryTableProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryTableProvider.java
index efacce3..7d2c7bc 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryTableProvider.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryTableProvider.java
@@ -394,4 +394,8 @@
 		this.currentFile = file;
 		this.currentRevision = getRevision(this.currentFile);
 	}
+
+	public ICVSFile getICVSFile() {
+		return this.currentFile;
+	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java
index 2bbb38c..04e157e 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/HistoryView.java
@@ -22,7 +22,11 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuListener;
@@ -33,7 +37,6 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.ITextOperationTarget;
@@ -65,8 +68,10 @@
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.team.core.RepositoryProvider;
 import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.subscribers.SyncInfo;
 import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
+import org.eclipse.team.internal.ccvs.core.CVSSyncInfo;
 import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.core.CVSTeamProvider;
 import org.eclipse.team.internal.ccvs.core.ICVSFile;
@@ -79,9 +84,17 @@
 import org.eclipse.team.internal.ccvs.ui.actions.CVSAction;
 import org.eclipse.team.internal.ccvs.ui.actions.MoveRemoteTagAction;
 import org.eclipse.team.internal.ccvs.ui.actions.OpenLogEntryAction;
+import org.eclipse.team.internal.ui.jobs.JobBusyCursor;
+import org.eclipse.team.internal.ui.jobs.JobStatusHandler;
+import org.eclipse.team.internal.ui.sync.compare.SyncInfoCompareInput;
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IActionDelegate;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPartListener;
 import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 import org.eclipse.ui.help.WorkbenchHelp;
@@ -113,6 +126,7 @@
 	private Action getRevisionAction;
 	private Action refreshAction;
 	private Action tagWithExistingAction;
+	private Action linkWithEditorAction;
 	
 	private SashForm sashForm;
 	private SashForm innerSashForm;
@@ -121,9 +135,58 @@
 	private Image versionImage;
 	
 	private ILogEntry currentSelection;
+	private boolean linkingEnabled;
+	
+	private IPreferenceStore settings;
+	
+	private FetchLogEntriesJob fetchLogEntriesJob;
+	private JobBusyCursor jobBusyCursor;
 	
 	public static final String VIEW_ID = "org.eclipse.team.ccvs.ui.HistoryView"; //$NON-NLS-1$
 	
+	private IPartListener partListener = new IPartListener() {
+		public void partActivated(IWorkbenchPart part) {
+			if (part instanceof IEditorPart)
+				editorActivated((IEditorPart) part);
+		}
+		public void partBroughtToTop(IWorkbenchPart part) {
+		}
+		public void partClosed(IWorkbenchPart part) {
+		}
+		public void partDeactivated(IWorkbenchPart part) {
+		}
+		public void partOpened(IWorkbenchPart part) {
+		}
+	};
+	private QualifiedName HISTORY_VIEW_JOB_TYPE = new QualifiedName(VIEW_ID, "jobs"); //$NON-NLS-1$
+
+	private class FetchLogEntriesJob extends Job {
+		public ICVSRemoteFile remoteFile;
+		public FetchLogEntriesJob() {
+			super(Policy.bind("HistoryView.fetchHistoryJob"));  //$NON-NLS-1$;
+		}
+		public void setRemoteFile(ICVSRemoteFile file) {
+			this.remoteFile = file;
+		}
+		public IStatus run(IProgressMonitor monitor) {
+			try {
+				entries = remoteFile.getLogEntries(monitor);
+				final String revisionId = remoteFile.getRevision();
+				tableViewer.getTable().getDisplay().asyncExec(new Runnable() {
+					public void run() {
+						if(tableViewer != null && ! tableViewer.getTable().isDisposed()) {
+							tableViewer.add(entries);
+								selectRevision(revisionId);
+						}
+					}
+				});
+				return Status.OK_STATUS;
+			} catch (TeamException e) {
+				return e.getStatus();
+			}
+		}
+	};
+	
 	/**
 	 * Adds the action contributions for this view.
 	 */
@@ -139,6 +202,16 @@
 		refreshAction.setDisabledImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH_DISABLED));
 		refreshAction.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_REFRESH));
 		
+		//	Link with Editor (toolbar)
+		 linkWithEditorAction = new Action(Policy.bind("HistoryView.linkWithLabel"), plugin.getImageDescriptor(ICVSUIConstants.IMG_LINK_WITH_EDITOR_ENABLED)) { //$NON-NLS-1$
+			 public void run() {
+				 setLinkingEnabled(isChecked());
+			 }
+		 };
+		linkWithEditorAction.setToolTipText(Policy.bind("HistoryView.linkWithLabel")); //$NON-NLS-1$
+		linkWithEditorAction.setHoverImageDescriptor(plugin.getImageDescriptor(ICVSUIConstants.IMG_LINK_WITH_EDITOR));
+		linkWithEditorAction.setChecked(isLinkingEnabled());
+		
 		// Double click open action
 		openAction = new OpenLogEntryAction();
 		tableViewer.getTable().addListener(SWT.DefaultSelection, new Listener() {
@@ -272,6 +345,7 @@
 		// Create the local tool bar
 		IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager();
 		tbm.add(refreshAction);
+		tbm.add(linkWithEditorAction);
 		tbm.update(false);
 	
 		// Create actions for the text editor
@@ -316,20 +390,34 @@
 	 * Method declared on IWorkbenchPart
 	 */
 	public void createPartControl(Composite parent) {
+		settings = CVSUIPlugin.getPlugin().getPreferenceStore();
+		this.linkingEnabled = settings.getBoolean(ICVSUIConstants.PREF_HISTORY_VIEW_EDITOR_LINKING);
+
 		initializeImages();
+		
 		sashForm = new SashForm(parent, SWT.VERTICAL);
 		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
 		tableViewer = createTable(sashForm);
 		innerSashForm = new SashForm(sashForm, SWT.HORIZONTAL);
 		tagViewer = createTagTable(innerSashForm);
 		textViewer = createText(innerSashForm);
 		sashForm.setWeights(new int[] { 70, 30 });
 		innerSashForm.setWeights(new int[] { 50, 50 });
+		
 		contributeActions();
+		
 		setViewerVisibility();
+		
 		// set F1 help
 		WorkbenchHelp.setHelp(sashForm, IHelpContextIds.RESOURCE_HISTORY_VIEW);
 		initDragAndDrop();
+		
+		//	Create the busy cursor with no control to start with (createViewer will set it)
+		 jobBusyCursor = new JobBusyCursor(parent, HISTORY_VIEW_JOB_TYPE);
+		 
+		// add listener for editor page activation - this is to support editor linking
+		getSite().getPage().addPartListener(partListener);		
 	}
 	private void initializeImages() {
 		CVSUIPlugin plugin = CVSUIPlugin.getPlugin();
@@ -356,24 +444,20 @@
 				if (!(inputElement instanceof ICVSRemoteFile)) return null;
 				final ICVSRemoteFile remoteFile = (ICVSRemoteFile)inputElement;
 				final Object[][] result = new Object[1][];
-				try {
-					new ProgressMonitorDialog(getViewer().getTable().getShell()).run(true, true, new IRunnableWithProgress() {
-						public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-							try {
-								entries = remoteFile.getLogEntries(monitor);
-								result[0] = entries;
-							} catch (TeamException e) {
-								throw new InvocationTargetException(e);
-							}
-						}
-					});
-				} catch (InterruptedException e) { // ignore cancellation
-					result[0] = new Object[0];
-				} catch (InvocationTargetException e) {
-					CVSUIPlugin.openError(getViewSite().getShell(), null, null, e);
-					result[0] = new Object[0];
+				if(fetchLogEntriesJob == null) {
+					fetchLogEntriesJob = new FetchLogEntriesJob();
 				}
-				return result[0];				
+				if(fetchLogEntriesJob.getState() != Job.NONE) {
+					fetchLogEntriesJob.cancel();
+					try {
+						fetchLogEntriesJob.join();
+					} catch (InterruptedException e) {
+						CVSUIPlugin.log(new CVSException(Policy.bind("HistoryView.errorFetchingEntries", remoteFile.getName()), e)); //$NON-NLS-1$
+					}
+				}
+				fetchLogEntriesJob.setRemoteFile(remoteFile);
+				JobStatusHandler.schedule(fetchLogEntriesJob, HISTORY_VIEW_JOB_TYPE);
+				return new Object[0];
 			}
 			public void dispose() {
 			}
@@ -468,6 +552,8 @@
 			versionImage.dispose();
 			versionImage = null;
 		}
+		getSite().getPage().removePartListener(partListener);
+		jobBusyCursor.dispose();
 	}	
 	/**
 	 * Returns the table viewer contained in this view.
@@ -547,10 +633,12 @@
 				try {
 					// for a file this will return the base
 					ICVSRemoteFile remoteFile = (ICVSRemoteFile)CVSWorkspaceRoot.getRemoteResourceFor(file);
-					historyTableProvider.setFile(remoteFile);
-					tableViewer.setInput(remoteFile);
-					setTitle(Policy.bind("HistoryView.titleWithArgument", remoteFile.getName())); //$NON-NLS-1$
-					selectRevision(remoteFile.getRevision());
+					if(remoteFile != null) {
+						historyTableProvider.setFile(remoteFile);
+						tableViewer.setInput(remoteFile);
+						setTitle(Policy.bind("HistoryView.titleWithArgument", remoteFile.getName())); //$NON-NLS-1$
+						selectRevision(remoteFile.getRevision());
+					}
 				} catch (TeamException e) {
 					CVSUIPlugin.openError(getViewSite().getShell(), null, null, e);
 				}				
@@ -563,6 +651,45 @@
 	}
 	
 	/**
+	 * An editor has been activated.  Sets the selection in this navigator to be the editor's input, if 
+	 * linking is enabled.
+	 * 
+	 * @param editor the active editor
+	 * @since 2.0
+	 */
+	protected void editorActivated(IEditorPart editor) {
+		if (!isLinkingEnabled()) {
+			return;
+		}
+		IEditorInput input = editor.getEditorInput();
+		// Handle compare editors opened from the Synchronize View
+		if (input instanceof SyncInfoCompareInput) {
+			SyncInfoCompareInput syncInput = (SyncInfoCompareInput) input;
+			SyncInfo info = syncInput.getSyncInfo();
+			if(info instanceof CVSSyncInfo && info.getLocal().getType() == IResource.FILE) {
+				ICVSRemoteFile remote = (ICVSRemoteFile)info.getRemote();
+				ICVSRemoteFile base = (ICVSRemoteFile)info.getBase();
+				if(remote != null) {
+					showHistory(remote);
+				} else if(base != null) {
+					showHistory(base);
+				}
+			}
+		// Handle editors opened on remote files
+		} else if(input instanceof RemoteFileEditorInput) {
+			ICVSRemoteFile remote = ((RemoteFileEditorInput)input).getCVSRemoteFile();
+			if(remote != null) {
+				showHistory(remote);
+			}
+		// Handle regular file editors
+		} else if (input instanceof IFileEditorInput) {
+			IFileEditorInput fileInput = (IFileEditorInput) input;
+			IFile file = fileInput.getFile();
+			showHistory(file);			
+		}
+	}
+	
+	/**
 	 * Shows the history for the given ICVSRemoteFile in the view.
 	 */
 	public void showHistory(ICVSRemoteFile remoteFile) {
@@ -572,11 +699,12 @@
 				setTitle(Policy.bind("HistoryView.title")); //$NON-NLS-1$
 				return;
 			}
+			ICVSFile existingFile = historyTableProvider.getICVSFile(); 
+			if(existingFile != null && existingFile.equals(remoteFile)) return;
 			this.file = null;
 			historyTableProvider.setFile(remoteFile);
 			tableViewer.setInput(remoteFile);
 			setTitle(Policy.bind("HistoryView.titleWithArgument", remoteFile.getName())); //$NON-NLS-1$
-			selectRevision(remoteFile.getRevision());
 		} catch (TeamException e) {
 			CVSUIPlugin.openError(getViewSite().getShell(), null, null, e);
 		} 
@@ -679,21 +807,48 @@
 	 * Select the revision in the receiver.
 	 */
 	public void selectRevision(String revision) {
-			if (entries == null) {
-				return;
-			}
-		
-			ILogEntry entry = null;
-			for (int i = 0; i < entries.length; i++) {
-				if (entries[i].getRevision().equals(revision)) {
-					entry = entries[i];
-					break;
-				}
-			}
-		
-			if (entry != null) {
-				IStructuredSelection selection = new StructuredSelection(entry);
-				tableViewer.setSelection(selection, true);
+		if (entries == null) {
+			return;
+		}
+	
+		ILogEntry entry = null;
+		for (int i = 0; i < entries.length; i++) {
+			if (entries[i].getRevision().equals(revision)) {
+				entry = entries[i];
+				break;
 			}
 		}
+	
+		if (entry != null) {
+			IStructuredSelection selection = new StructuredSelection(entry);
+			tableViewer.setSelection(selection, true);
+		}
+	}
+	
+	/**
+	 * Enabled linking to the active editor
+	 * @since 3.0
+	 */
+	public void setLinkingEnabled(boolean enabled) {
+		this.linkingEnabled = enabled;
+
+		// remember the last setting in the dialog settings		
+		settings.setValue(ICVSUIConstants.PREF_HISTORY_VIEW_EDITOR_LINKING, enabled);
+	
+		// if turning linking on, update the selection to correspond to the active editor
+		if (enabled) {
+			IEditorPart editor = getSite().getPage().getActiveEditor();
+			if (editor != null) {
+				editorActivated(editor);
+			}
+		}
+	}
+	
+	/**
+	 * Returns if linking to the ative editor is enabled or disabled.
+	 * @return boolean indicating state of editor linking.
+	 */
+	private boolean isLinkingEnabled() {
+		return linkingEnabled;
+	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java
index 4e800db..1d8c2b7 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ICVSUIConstants.java
@@ -38,15 +38,17 @@
 	public final String IMG_REFRESH = "clcl16/refresh.gif"; //$NON-NLS-1$
 	public final String IMG_CLEAR = "clcl16/clear_co.gif"; //$NON-NLS-1$
 	public final String IMG_COLLAPSE_ALL = "clcl16/collapseall.gif"; //$NON-NLS-1$
+	public final String IMG_LINK_WITH_EDITOR = "clcl16/synced.gif"; //$NON-NLS-1$
 	
 	// toolbar (disabled)
 	public final String IMG_REFRESH_DISABLED = "dlcl16/refresh.gif"; //$NON-NLS-1$
 	public final String IMG_CLEAR_DISABLED = "dlcl16/clear_co.gif"; //$NON-NLS-1$
-	
+		
 	// toolbar (enabled)
 	public final String IMG_REFRESH_ENABLED = "elcl16/refresh.gif"; //$NON-NLS-1$
 	public final String IMG_CLEAR_ENABLED = "elcl16/clear_co.gif"; //$NON-NLS-1$
 	public final String IMG_COLLAPSE_ALL_ENABLED = "elcl16/collapseall.gif"; //$NON-NLS-1$
+	public final String IMG_LINK_WITH_EDITOR_ENABLED = "elcl16/synced.gif"; //$NON-NLS-1$
 	
 	// wizards
 	public final String IMG_NEWLOCATION = "wizards/newlocation_wiz.gif"; //$NON-NLS-1$
@@ -54,6 +56,7 @@
 	// preferences
 	public final String PREF_SHOW_COMMENTS = "pref_show_comments"; //$NON-NLS-1$
 	public final String PREF_SHOW_TAGS = "pref_show_tags"; //$NON-NLS-1$
+	public final String PREF_HISTORY_VIEW_EDITOR_LINKING = "pref_history_view_linking"; //$NON-NLS-1$
 	public final String PREF_PRUNE_EMPTY_DIRECTORIES = "pref_prune_empty_directories";	 //$NON-NLS-1$
 	public final String PREF_TIMEOUT = "pref_timeout";	 //$NON-NLS-1$
 	public final String PREF_QUIETNESS = "pref_quietness"; //$NON-NLS-1$
@@ -135,8 +138,8 @@
 	public final int OPTION_AUTOMATIC = 3;
 	
 	// work in progress preferences
-	public final String BACKGROUND_REPOVIEW = PREFIX + "background_repoview";
-	public final String BACKGROUND_OPERATIONS = PREFIX + "background_operations";
-	public final String USE_NEW_SYNCVIEW = PREFIX + "old_sync_view";
+	public final String BACKGROUND_REPOVIEW = PREFIX + "background_repoview"; //$NON-NLS-1$
+	public final String BACKGROUND_OPERATIONS = PREFIX + "background_operations"; //$NON-NLS-1$
+	public final String USE_NEW_SYNCVIEW = PREFIX + "old_sync_view"; //$NON-NLS-1$
 }
 
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIcon.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIcon.java
deleted file mode 100644
index a7e0c40..0000000
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIcon.java
+++ /dev/null
@@ -1,80 +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.ui;
-
-import java.util.Arrays;
-
-import org.eclipse.jface.resource.CompositeImageDescriptor;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-
-/**
- * An OverlayIcon consists of a main icon and several adornments.
- */
-public abstract class OverlayIcon extends CompositeImageDescriptor {
-	// the base image
-	private Image base;
-	// the overlay images
-	private ImageDescriptor[] overlays;
-	// the size
-	private Point size;
-	// the locations
-	private int[] locations;
-	
-	public static final int TOP_LEFT = 0;
-	public static final int TOP_RIGHT = 1;
-	public static final int BOTTOM_LEFT = 2;
-	public static final int BOTTOM_RIGHT = 3;
-	
-	/**
-	 * OverlayIcon constructor.
-	 * 
-	 * @param base the base image
-	 * @param overlays the overlay images
-	 * @param locations the location of each image
-	 * @param size the size
-	 */
-	public OverlayIcon(Image base, ImageDescriptor[] overlays, int[] locations, Point size) {
-		this.base = base;
-		this.overlays = overlays;
-		this.locations = locations;
-		this.size = size;
-	}
-	/**
-	 * Superclasses override to draw the overlays.
-	 */
-	protected abstract void drawOverlays(ImageDescriptor[] overlays, int[] locations);
-
-	public boolean equals(Object o) {
-		if (! (o instanceof OverlayIcon)) return false;
-		OverlayIcon other = (OverlayIcon) o;
-		return base.equals(other.base) && Arrays.equals(overlays, other.overlays);
-	}
-
-	public int hashCode() {
-		int code = base.hashCode();
-		for (int i = 0; i < overlays.length; i++) {
-			code ^= overlays[i].hashCode();
-		}
-		return code;
-	}
-
-
-	protected void drawCompositeImage(int width, int height) {
-		drawImage(base.getImageData(), 0, 0);
-		drawOverlays(overlays, locations);
-	}
-
-	protected Point getSize() {
-		return size;
-	}
-}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIconCache.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIconCache.java
index fc7baf1..c6c06b1 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIconCache.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/OverlayIconCache.java
@@ -15,6 +15,7 @@
 import java.util.Map;
 
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.team.internal.ui.*;
 
 /**
  * Maintains a cache of OverlayIcons.
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteFileEditorInput.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteFileEditorInput.java
index 99b9155..a5401a7 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteFileEditorInput.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteFileEditorInput.java
@@ -192,4 +192,13 @@
 	public String getToolTipText() {
 		return getFullPath();
 	}
+	
+	/**
+	 * Returns the remote CVS file shown in this editor input.
+	 * @return the remote file handle.
+	 */
+	public ICVSRemoteFile getCVSRemoteFile() {
+		return file;
+	}
+
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java
index 316158e..5291ada 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/RemoteRevisionQuickDiffProvider.java
@@ -19,46 +19,193 @@
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.IDocument;
-import org.eclipse.team.core.sync.IRemoteResource;
+import org.eclipse.team.core.subscribers.ITeamResourceChangeListener;
+import org.eclipse.team.core.subscribers.TeamDelta;
 import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
+import org.eclipse.team.internal.ccvs.core.ICVSFile;
+import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.editors.quickdiff.IQuickDiffProviderImplementation;
-import org.eclipse.ui.editors.text.StorageDocumentProvider;
+import org.eclipse.ui.editors.text.IStorageDocumentProvider;
 import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.IElementStateListener;
 import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.quickdiff.IQuickDiffProviderImplementation;
 
 /**
- * Quick and dirty cvs reference provider. No background, no hourglass cursor, no nothing.
+ * The CVS quick diff provider that returns the latest remote revision for a file
+ * that is managed by the CVS provider.
+ * 
+ * 
+ * 
  * @since 3.0
  */
 public class RemoteRevisionQuickDiffProvider implements IQuickDiffProviderImplementation {
 
-	private boolean fDocumentRead= false;
-	private ITextEditor fEditor= null;
-	private IDocument fReference= null;
+	private boolean fDocumentRead = false;
+	private ITextEditor fEditor = null;
+	private IDocument fReference = null;
+	private IDocumentProvider documentProvider = null;
+	private IEditorInput input = null;
 	private String fId;
+	private ICVSFile cvsFile;
 
+	protected Job updateJob;
+	
+	/**
+	 * Updates the document if a sync changes occurs to the associated CVS file.
+	 */
+	private ITeamResourceChangeListener teamChangeListener = new ITeamResourceChangeListener() {
+		public void teamResourceChanged(TeamDelta[] deltas) {
+			if(cvsFile != null) {
+				for (int i = 0; i < deltas.length; i++) {
+					TeamDelta delta = deltas[i];
+					try {
+						if(delta.getResource().equals(cvsFile.getIResource())) {
+							if(delta.getFlags() == TeamDelta.SYNC_CHANGED) {
+								fetchContentsInJob();
+							}
+						}
+					} catch (CVSException e) {
+						e.printStackTrace();
+					} 
+				}
+			}
+		}
+	};
+
+	/**
+	 * Updates the document if the document is changed (e.g. replace with)
+	 */
+	private IElementStateListener documentListener = new IElementStateListener() {
+		public void elementDirtyStateChanged(Object element, boolean isDirty) {
+		}
+
+		public void elementContentAboutToBeReplaced(Object element) {
+		}
+
+		public void elementContentReplaced(Object element) {
+			if(element == input) {
+				fetchContentsInJob();
+			}
+		}
+
+		public void elementDeleted(Object element) {
+		}
+
+		public void elementMoved(Object originalElement, Object movedElement) {
+		}
+	};
+	
 	/*
 	 * @see org.eclipse.test.quickdiff.DocumentLineDiffer.IQuickDiffReferenceProvider#getReference()
 	 */
-	public IDocument getReference() {
-		if (!fDocumentRead)
-			readDocument();
-		if (fDocumentRead)
-			return fReference;
-		else
+	public IDocument getReference(IProgressMonitor monitor) {
+		try {
+			if (!fDocumentRead)
+				readDocument(monitor);
+			if (fDocumentRead)
+				return fReference;
+			else
+				return null;
+		} catch(CoreException e) {
+			CVSUIPlugin.log(e);
 			return null;
+		}
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.texteditor.quickdiff.IQuickDiffProviderImplementation#setActiveEditor(org.eclipse.ui.texteditor.ITextEditor)
+	 */
+	public void setActiveEditor(ITextEditor targetEditor) {
+		if (targetEditor != fEditor) {
+			dispose();
+			fEditor= targetEditor;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.texteditor.quickdiff.IQuickDiffProviderImplementation#isEnabled()
+	 */
+	public boolean isEnabled() {
+		if (!initialized())
+			return false;
+		return getCVSFile() != null;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.source.diff.DocumentLineDiffer.IQuickDiffReferenceProvider#dispose()
+	 */
+	public void dispose() {
+		fReference= null;
+		cvsFile = null;
+		fDocumentRead= false;
+		if(documentProvider != null) {
+			documentProvider.removeElementStateListener(documentListener);
+		}
+		CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().removeListener(teamChangeListener);
+	}
+
+	/*
+	 * @see org.eclipse.quickdiff.QuickDiffTestPlugin.IQuickDiffProviderImplementation#setId(java.lang.String)
+	 */
+	public void setId(String id) {
+		fId= id;
+	}
+
+	/*
+	 * @see org.eclipse.jface.text.source.diff.DocumentLineDiffer.IQuickDiffReferenceProvider#getId()
+	 */
+	public String getId() {
+		return fId;
+	}
+	
+	private boolean initialized() {
+		return fEditor != null;
+	}
+	
+	private void readDocument(IProgressMonitor monitor) throws CoreException {
+		if (!initialized())
+			return;
+
+		fDocumentRead= false;
+	
+		if (fReference == null) {
+			fReference= new Document();
+		}
+	
+		cvsFile = getCVSFile();
+		if(cvsFile != null) {
+			ICVSRemoteResource remote = CVSWorkspaceRoot.getRemoteTree(cvsFile.getIResource(), cvsFile.getSyncInfo().getTag(), monitor);
+			IDocumentProvider docProvider= fEditor.getDocumentProvider();
+			if (docProvider instanceof IStorageDocumentProvider) {
+				documentProvider = docProvider;
+				IStorageDocumentProvider provider= (IStorageDocumentProvider) documentProvider;			
+				String encoding= provider.getEncoding(fEditor.getEditorInput());
+				if (encoding == null) {
+					encoding= provider.getDefaultEncoding();
+				}
+				InputStream stream= remote.getContents(monitor);
+				if (stream == null) {
+					return;
+				}
+				setDocumentContent(fReference, stream, encoding);
+				
+				CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().addListener(teamChangeListener);
+				((IDocumentProvider)provider).addElementStateListener(documentListener);
+			}
+		}
+		fDocumentRead= true;
+	}
+	
 	/**
 	 * Intitializes the given document with the given stream using the given encoding.
 	 *
@@ -82,108 +229,51 @@
 			}
 			document.set(caw.toString());
 		} catch (IOException x) {
-			String msg= x.getMessage() == null ? "" : x.getMessage(); //$NON-NLS-1$
-			IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, msg, x);
-			throw new CoreException(s);
+			throw new CVSException(Policy.bind("RemoteRevisionQuickDiffProvider.readingFile"), x);
 		} finally {
 			if (in != null) {
 				try {
 					in.close();
 				} catch (IOException x) {
+					throw new CVSException(Policy.bind("RemoteRevisionQuickDiffProvider.closingFile"), x);
 				}
 			}
 		}
 	}
-
-	private void readDocument() {
-		// TODO this is quick&dirty
-		if (!initialized())
-			return;
-		fDocumentRead= false;
+	
+	private ICVSFile getCVSFile() {
 		IEditorInput input= fEditor.getEditorInput();
-		if (fReference == null)
-			fReference= new Document();
 		if (input instanceof IFileEditorInput) {
 			IFile file= ((IFileEditorInput)input).getFile();
-			IRemoteResource remote= null;
 			try {
-				remote= CVSWorkspaceRoot.getRemoteResourceFor(file);
+				if(CVSWorkspaceRoot.isSharedWithCVS(file)) {
+					return CVSWorkspaceRoot.getCVSFileFor(file);
+				}
 			} catch (CVSException e) {
-				return;
+				CVSUIPlugin.log(e);
 			}
-			if (remote == null)
-				return;
+		}
+		return null;
+	}
 
-			IDocumentProvider provider= fEditor.getDocumentProvider();
-			if (provider instanceof StorageDocumentProvider) {
-				StorageDocumentProvider sProvider= (StorageDocumentProvider)provider;
-				String encoding= sProvider.getEncoding(input);
-				if (encoding == null)
-					encoding= sProvider.getDefaultEncoding();
+	private void fetchContentsInJob() {
+		if(updateJob != null && updateJob.getState() != Job.NONE) {
+			updateJob.cancel();
+			try {
+				updateJob.join();
+			} catch (InterruptedException e) {				
+			}
+		}
+		Job updateJob = new Job(Policy.bind("RemoteRevisionQuickDiffProvider.fetchingFile")) {
+			protected IStatus run(IProgressMonitor monitor) {
 				try {
-					InputStream stream= remote.getContents(new NullProgressMonitor());
-					if (stream == null)
-						return;
-					setDocumentContent(fReference, stream, encoding);
-				} catch (CoreException e1) {
-					// TODO Auto-generated catch block
-					MessageDialog.openError(fEditor.getSite().getShell(), "CoreException", "Error when retrieving remote version");
-					return;
+					readDocument(monitor);
+				} catch (CoreException e) {
+					return e.getStatus();
 				}
+				return Status.OK_STATUS;
 			}
-		}
-		fDocumentRead= true;
-	}
-
-	private boolean initialized() {
-		return fEditor != null;
-	}
-
-	public void setActiveEditor(ITextEditor targetEditor) {
-		if (targetEditor != fEditor) {
-			dispose();
-			fEditor= targetEditor;
-		}
-	}
-
-	/*
-	 * @see org.eclipse.quickdiff.QuickDiffTestPlugin.IQuickDiffProviderImplementation#isEnabled()
-	 */
-	public boolean isEnabled() {
-		if (!initialized())
-			return false;
-		IEditorInput input= fEditor.getEditorInput();
-		if (input instanceof IFileEditorInput) {
-			IFile file= ((IFileEditorInput)input).getFile();
-			try {
-				return CVSWorkspaceRoot.isSharedWithCVS(file);
-			} catch (CVSException e) {
-				// TODO: handle exception
-				e.printStackTrace();
-			}
-		}
-		return false;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.source.diff.DocumentLineDiffer.IQuickDiffReferenceProvider#dispose()
-	 */
-	public void dispose() {
-		fReference= null;
-		fDocumentRead= false;
-	}
-
-	/*
-	 * @see org.eclipse.quickdiff.QuickDiffTestPlugin.IQuickDiffProviderImplementation#setId(java.lang.String)
-	 */
-	public void setId(String id) {
-		fId= id;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.source.diff.DocumentLineDiffer.IQuickDiffReferenceProvider#getId()
-	 */
-	public String getId() {
-		return fId;
+		};
+		updateJob.schedule();
 	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagAsVersionDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagAsVersionDialog.java
index 9681df4..189affb 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagAsVersionDialog.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagAsVersionDialog.java
@@ -105,7 +105,7 @@
 		);
 		
 		moveTagButton = new Button(parent, SWT.CHECK);
-		moveTagButton.setText(Policy.bind("TagAction.moveTag"));
+		moveTagButton.setText(Policy.bind("TagAction.moveTag")); //$NON-NLS-1$
 		moveTagButton.setLayoutData(new GridData(
 			GridData.GRAB_HORIZONTAL |
 			GridData.GRAB_VERTICAL |
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkInProgressPreferencePage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkInProgressPreferencePage.java
index 88ea85f..edec1e5 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkInProgressPreferencePage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkInProgressPreferencePage.java
@@ -16,13 +16,14 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.team.internal.ccvs.ui.Policy;
 
 public class WorkInProgressPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
 	
 	public WorkInProgressPreferencePage() {
 		super(GRID);
-		setTitle("CVS Work In Progress");
-		setDescription("Preferences for enabling features that are not complete:");
+		setTitle(Policy.bind("WorkInProgressPreferencePage.0")); //$NON-NLS-1$
+		setDescription(Policy.bind("WorkInProgressPreferencePage.1")); //$NON-NLS-1$
 		setPreferenceStore(CVSUIPlugin.getPlugin().getPreferenceStore());
 	}
 
@@ -38,9 +39,9 @@
 	 * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors()
 	 */
 	public void createFieldEditors() {		
-		addField(new BooleanFieldEditor(ICVSUIConstants.BACKGROUND_REPOVIEW, "Enable background fetching of resources in the CVS Repositories view", SWT.NONE, getFieldEditorParent()));	
-		addField(new BooleanFieldEditor(ICVSUIConstants.BACKGROUND_OPERATIONS, "Enable operations to be run in the background (e.g. checkout, update, commit)", SWT.NONE, getFieldEditorParent()));
-		addField(new BooleanFieldEditor(ICVSUIConstants.USE_NEW_SYNCVIEW, "Enable the CVS sync actions to open the new sync view", SWT.NONE, getFieldEditorParent()));
+		addField(new BooleanFieldEditor(ICVSUIConstants.BACKGROUND_REPOVIEW, Policy.bind("WorkInProgressPreferencePage.2"), SWT.NONE, getFieldEditorParent()));	 //$NON-NLS-1$
+		addField(new BooleanFieldEditor(ICVSUIConstants.BACKGROUND_OPERATIONS, Policy.bind("WorkInProgressPreferencePage.3"), SWT.NONE, getFieldEditorParent())); //$NON-NLS-1$
+		addField(new BooleanFieldEditor(ICVSUIConstants.USE_NEW_SYNCVIEW, Policy.bind("WorkInProgressPreferencePage.4"), SWT.NONE, getFieldEditorParent())); //$NON-NLS-1$
 	}
 	
 	/* (non-Javadoc)
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddToWorkspaceAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddToWorkspaceAction.java
index 8d13812..b415083 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddToWorkspaceAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddToWorkspaceAction.java
@@ -146,7 +146,7 @@
 		IResource[] projects = (IResource[]) targetProjects.toArray(new IResource[targetProjects.size()]);
 		PromptingDialog prompt = new PromptingDialog(getShell(), projects, 
 													  getOverwriteLocalAndFileSystemPrompt(), 
-													  Policy.bind("ReplaceWithAction.confirmOverwrite"),
+													  Policy.bind("ReplaceWithAction.confirmOverwrite"), //$NON-NLS-1$
 													  true /* all or nothing*/);//$NON-NLS-1$
 		return (prompt.promptForMultiple().length == projects.length);
 	}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CheckoutAsAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CheckoutAsAction.java
index 36a3793..0b426ab 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CheckoutAsAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CheckoutAsAction.java
@@ -20,7 +20,6 @@
 import org.eclipse.team.internal.ccvs.ui.Policy;
 import org.eclipse.team.internal.ccvs.ui.operations.HasProjectMetaFileOperation;
 import org.eclipse.team.internal.ccvs.ui.wizards.CheckoutAsWizard;
-import org.eclipse.ui.PlatformUI;
 
 /**
  * Add a remote resource to the workspace. Current implementation:
@@ -45,7 +44,7 @@
 	
 	protected boolean allowProjectConfiguration(ICVSRemoteFolder[] folders) throws CVSException, InterruptedException {
 		if (folders.length != 1) return false;
-		return !HasProjectMetaFileOperation.hasMetaFile(getShell(), folders[0], PlatformUI.getWorkbench().getActiveWorkbenchWindow());	
+		return !HasProjectMetaFileOperation.hasMetaFile(getShell(), folders[0]);	
 	}
 	
 	/*
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CommitAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CommitAction.java
index d432e8b..1e7d831 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CommitAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CommitAction.java
@@ -130,7 +130,7 @@
 						// no need to go into children because add is deep
 						return false;
 					}
-				}, IResource.DEPTH_INFINITE, true /* include phantoms */);
+				});
 			} catch (CoreException e) {
 				throw CVSException.wrapException(e);
 			}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/RestoreFromRepositoryAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/RestoreFromRepositoryAction.java
index c82b3a1..95c1224 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/RestoreFromRepositoryAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/RestoreFromRepositoryAction.java
@@ -180,7 +180,7 @@
 		monitor.beginTask(null, 100);
 		AtticLogListener listener = new AtticLogListener();
 		Session session = new Session(location, parent, true /* output to console */);
-		session.open(Policy.subMonitorFor(monitor, 10));
+		session.open(Policy.subMonitorFor(monitor, 10), false /* read-only */);
 		try {
 			QuietOption quietness = CVSProviderPlugin.getPlugin().getQuietness();
 			try {
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java
index eb68306..8ef0d31 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java
@@ -114,7 +114,7 @@
 			final FolderSyncInfo info = folder.getFolderSyncInfo();
 			ICVSRepositoryLocation location = CVSProviderPlugin.getPlugin().getRepository(info.getRoot());
 			Session session = new Session(location, folder, true /* output to console */);
-			session.open(Policy.subMonitorFor(monitor, 10));
+			session.open(Policy.subMonitorFor(monitor, 10), false /* read-only */);
 			try {
 				Command.QuietOption quietness = CVSProviderPlugin.getPlugin().getQuietness();
 				try {
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/TagAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/TagAction.java
index 095b169..5dece06 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/TagAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/TagAction.java
@@ -94,7 +94,7 @@
 		if (dialog.shouldMoveTag() && store.getBoolean(ICVSUIConstants.PREF_CONFIRM_MOVE_TAG))  {
 			MessageDialogWithToggle confirmDialog = MessageDialogWithToggle.openQuestion(getShell(), 
 				Policy.bind("TagAction.moveTagConfirmTitle"),  //$NON-NLS-1$
-				Policy.bind("TagAction.moveTagConfirmMessage", dialog.getTagName()),
+				Policy.bind("TagAction.moveTagConfirmMessage", dialog.getTagName()), //$NON-NLS-1$
 				null,
 				false);
 			
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/MergeWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/MergeWizard.java
index aa8bc33..582ae67 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/MergeWizard.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/merge/MergeWizard.java
@@ -11,16 +11,11 @@
 package org.eclipse.team.internal.ccvs.ui.merge;
 
 
-import java.lang.reflect.InvocationTargetException;
-
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.subscribers.TeamProvider;
+import org.eclipse.team.core.subscribers.TeamSubscriber;
 import org.eclipse.team.internal.ccvs.core.CVSMergeSubscriber;
 import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
@@ -30,7 +25,6 @@
 import org.eclipse.team.ui.sync.ISynchronizeView;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkingSet;
 import org.eclipse.ui.PlatformUI;
 
 public class MergeWizard extends Wizard {
@@ -39,7 +33,6 @@
 	IResource[] resources;
 
 	public void addPages() {
-		setNeedsProgressMonitor(true);
 		// when merging multiple resources, use the tags found on the first selected
 		// resource. This makes sense because you would typically merge resources that
 		// have a common context and are versioned and branched together.
@@ -69,31 +62,16 @@
 		CVSTag startTag = startPage.getTag();
 		CVSTag endTag = endPage.getTag();				
 		
-		final CVSMergeSubscriber s = new CVSMergeSubscriber(resources, startTag, endTag);
-		try {
-			getContainer().run(false, true, new IRunnableWithProgress() {
-				public void run(IProgressMonitor monitor)	throws InvocationTargetException, InterruptedException {
-						try {
-							s.refresh(resources, IResource.DEPTH_INFINITE, monitor);
-						} catch (TeamException e) {
-							s.cancel();
-							throw new InvocationTargetException(e);
-						}
-						TeamProvider.registerSubscriber(s);
-				}
-			});
-			ISynchronizeView view = TeamUI.showSyncViewInActivePage(null /* no default page */);
-			IWorkingSet workingSet = CVSUIPlugin.getWorkingSet(resources, Policy.bind("SyncAction.workingSetName")); //$NON-NLS-1$
-			if(view != null) {
-				view.setWorkingSet(workingSet);
-				view.selectSubscriber(s);
-			} else {
-				CVSUIPlugin.openError(getContainer().getShell(), Policy.bind("error"), Policy.bind("Error.unableToShowSyncView"), null);
-			}
-		} catch (InvocationTargetException e) {
-			CVSUIPlugin.openError(getContainer().getShell(), null, null, e);
-			return false;
-		} catch (InterruptedException e) {
+		CVSMergeSubscriber s = new CVSMergeSubscriber(resources, startTag, endTag);
+		TeamSubscriber.getSubscriberManager().registerSubscriber(s);
+		
+		ISynchronizeView view = TeamUI.showSyncViewInActivePage(null);
+		if(view != null) {
+			view.setWorkingSet(null); /* show all resources in the merge */
+			view.selectSubscriber(s);
+			view.refreshWithRemote(s, resources);
+		} else {
+			CVSUIPlugin.openError(getShell(), Policy.bind("error"), Policy.bind("Error.unableToShowSyncView"), null); //$NON-NLS-1$ //$NON-NLS-2$
 			return false;
 		}
 		return true;
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties
index e784af5..1a9bc76 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties
@@ -377,6 +377,7 @@
 HistoryView.comment=Comment
 HistoryView.refreshLabel=&Refresh View
 HistoryView.refresh=Refresh View
+HistoryView.linkWithLabel=Link with &Editor
 HistoryView.selectAll=Select &All
 HistoryView.showComment=Show Comment Viewer
 HistoryView.showTags=Show Tag Viewer
@@ -384,6 +385,9 @@
 HistoryView.titleWithArgument=CVS Resource History - {0}
 HistoryView.overwriteTitle=Overwrite local changes?
 HistoryView.overwriteMsg=You have local changes. Do you want to overwrite them?
+HistoryView.fetchHistoryJob=Fetching CVS revision history
+HistoryView.fetchHistoryJobFile=Fetching CVS revision history for: {0}
+HistoryView.errorFetchingEntries=Error fetching entries for {0}
 
 IgnoreAction.ignore=Error Ignoring Resource
 
@@ -723,17 +727,6 @@
 ExtMethodPreferencePage_CVS_SERVER__7=CVS_&SERVER:
 UpdateMergeActionProblems_merging_remote_resources_into_workspace_1=Problems merging remote resources into workspace
 UpdateMergeActionProblems_merging_remote_resources_into_workspace_2=Problems merging remote resources into workspace
-CVSAddResolutionGenerator.Add_Resource_to_CVS_1=Add Resource to CVS
-CVSAddResolutionGenerator.Add_Resource_and_Children_to_CVS_2=Add Resource and Children to CVS
-CVSAddResolutionGenerator.Add_to_.cvsignore_3=Add to .cvsignore
-CVSRemoveResolutionGenerator.Commit_Deletion_to_CVS_1=Commit Deletion to CVS
-CVSRemoveResolutionGenerator.Undo_Deletion_from_Local_History_2=Undo Deletion from Local History
-CVSRemoveResolutionGenerator.No_local_history_available._Try_undoing_from_the_server_3=No local history available. Try undoing from the server
-CVSRemoveResolutionGenerator.Undo_Deletion_from_CVS_Server_4=Undo Deletion from CVS Server
-CVSRemoveResloutionGenerator.Commit_Deletion_to_CVS_1=Commit Deletion to CVS
-CVSRemoveResloutionGenerator.Undo_Deletion_from_Local_History_2=Undo Deletion from Local History
-CVSRemoveResloutionGenerator.No_local_history_available._Try_undoing_from_the_server_3=No local history available. Try undoing from the server
-CVSRemoveResloutionGenerator.Undo_Deletion_from_CVS_Server_4=Undo Deletion from CVS Server
 
 TagConfigurationDialog.1=Configure Branches and Versions for {0}
 TagConfigurationDialog.2=Configure Branches and Versions for {0} projects
@@ -917,7 +910,7 @@
 CheckoutOperation.scrubbingProject=Scrubbing project ''{0}''.
 CheckoutOperation.refreshingProject=Configuring project ''{0}''.
 
-CheckoutSingleProjectOperation.taskname=Checking out "{0}" from CVS as "{1}"
+CheckoutSingleProjectOperation.taskname=Checking out ''{0}'' from CVS
 CheckoutMultipleProjectsOperation.taskName=Checking out {0} folders from CVS
 
 CheckoutIntoOperation.taskname=Checking out {0} folders from CVS into ''{1}''
@@ -999,9 +992,6 @@
 CheckoutIntoProjectSelectionPage.recurse=&Checkout subfolders
 CheckoutIntoProjectSelectionPage.invalidFolderName=''{0}'' is not a valid folder name
 
-CVSOperation.workspaceOperationJobName=CVS workspace modify operation: {0}
-CVSOperation.operationJobName=CVS operation: {0}
-
 HasProjectMetaFile.taskName=Looking for a remote meta file
 TagFromWorkspace.taskName=Tagging from workspace
 TagFromRepository.taskName=Tagging from repository
@@ -1019,3 +1009,23 @@
 
 Error.unableToShowSyncView=Error opening Synchronize View. Please ensure that the Team plugin is installed correctly.
 ShowAnnotationAction.1=Unexpected response from CVS Server: {0}
+
+CVSSubscriberAction.jobName=Performing CVS operation on {0} resources.
+UpdateAction.jobName=Performing CVS update on {0} resources.
+MergeUpdateAction.jobName=Performing CVS merge on {0} resources.
+MergeUpdateAction.invalidSubscriber=Invalid subscriber: {0}
+CommitAction.jobName=Performing CVS commit on {0} resources.
+WorkInProgressPreferencePage.0=CVS Work In Progress
+WorkInProgressPreferencePage.1=Preferences for enabling features that are not complete:
+WorkInProgressPreferencePage.2=Enable background fetching of resources in the CVS Repositories view
+WorkInProgressPreferencePage.3=Enable operations to be run in the background (e.g. checkout, update, commit)
+WorkInProgressPreferencePage.4=Enable the CVS sync actions to open the new sync view
+CheckoutProjectOperation.8=Checking out ''{0}'' into project ''{0}''
+CheckoutProjectOperation.9=Checking out ''{0}'' into {1} projects
+CVSOperation.0=Errors occured in {0} of {1} operations.
+CVSDecorator.exceptionMessage=Errors occured while applying CVS decorations to resources.
+FetchMembersOperation.0=Fetching members of {0};
+
+RemoteRevisionQuickDiffProvider.readingFile=Error reading remote file
+RemoteRevisionQuickDiffProvider.closingFile=Error closing remote file
+RemoteRevisionQuickDiffProvider.fetchingFile=CVS QuickDiff: fetching remote contents for ''{0}''
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/BatchSimilarSchedulingRule.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/BatchSimilarSchedulingRule.java
deleted file mode 100644
index 9a461b9..0000000
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/BatchSimilarSchedulingRule.java
+++ /dev/null
@@ -1,33 +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.ui.model;
-
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-
-/**
- * A simple job scheduling rule for serializing jobs that shouldn't be run
- * concurrently.
- */
-public class BatchSimilarSchedulingRule implements ISchedulingRule {
-	public String id;
-	public BatchSimilarSchedulingRule(String id) {
-		this.id = id;
-	}		
-	public boolean isConflicting(ISchedulingRule rule) {
-		if(rule instanceof BatchSimilarSchedulingRule) {
-			return ((BatchSimilarSchedulingRule)rule).id.equals(id);
-		}
-		return false;
-	}
-	public boolean contains(ISchedulingRule rule) {		
-		return isConflicting(rule);
-	}
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java
index f1e2cc3..61cfffa 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/CVSTagElement.java
@@ -10,16 +10,24 @@
  *******************************************************************************/
 package org.eclipse.team.internal.ccvs.ui.model;
 
+import java.lang.reflect.InvocationTargetException;
+
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jface.progress.IElementCollector;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.team.core.TeamException;
+import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.CVSTag;
+import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
 import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
 import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
+import org.eclipse.team.internal.ccvs.ui.Policy;
+import org.eclipse.team.internal.ccvs.ui.operations.FetchMembersOperation;
+import org.eclipse.team.internal.ccvs.ui.operations.FetchMembersOperation.RemoteFolderFilter;
 import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
 
 public class CVSTagElement extends CVSModelElement implements IDeferredWorkbenchAdapter {
@@ -90,15 +98,36 @@
 	}
 	
 	public void fetchDeferredChildren(Object o, IElementCollector collector, IProgressMonitor monitor) {
-		try {
-			collector.add(fetchChildren(o, monitor), monitor);
-		} catch (TeamException e) {
-			CVSUIPlugin.log(e);
+		if (tag.getType() == CVSTag.HEAD) {
+			try {
+				monitor = Policy.monitorFor(monitor);
+				RemoteFolder folder = new RemoteFolder(null, root, ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME, tag);
+				monitor.beginTask(Policy.bind("RemoteFolderElement.fetchingRemoteChildren", root.toString()), 100); //$NON-NLS-1$
+				FetchMembersOperation operation = new FetchMembersOperation(null, folder, collector);
+				operation.setFilter(new RemoteFolderFilter() {
+					public ICVSRemoteResource[] filter(ICVSRemoteResource[] folders) {
+						return CVSUIPlugin.getPlugin().getRepositoryManager().filterResources(getWorkingSet(), folders);
+					}
+				});
+				operation.run(Policy.subMonitorFor(monitor, 100));
+			} catch (InvocationTargetException e) {
+				CVSUIPlugin.log(CVSException.wrapException(e));
+			} catch (InterruptedException e) {
+				// Cancelled by the user;
+			} finally {
+				monitor.done();
+			}
+		} else {
+			try {
+				collector.add(fetchChildren(o, monitor), monitor);
+			} catch (TeamException e) {
+				CVSUIPlugin.log(e);
+			}
 		}
 	}
 
-	public ISchedulingRule getRule() {
-		return new BatchSimilarSchedulingRule("org.eclipse.team.cvs.ui.model.tagelement"); //$NON-NLS-1$
+	public ISchedulingRule getRule(Object element) {
+		return new RepositoryLocationSchedulingRule(root); //$NON-NLS-1$
 	}
 	
 	public boolean isContainer() {
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteContentProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteContentProvider.java
index 1cbeb0d..a67476c 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteContentProvider.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteContentProvider.java
@@ -14,10 +14,12 @@
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
+import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
 import org.eclipse.team.internal.ccvs.core.ICVSResource;
 import org.eclipse.team.internal.ccvs.core.resources.RemoteResource;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
 import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
+import org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot;
 import org.eclipse.ui.IWorkingSet;
 import org.eclipse.ui.model.WorkbenchContentProvider;
 import org.eclipse.ui.progress.DeferredTreeContentManager;
@@ -99,9 +101,35 @@
 	public Object[] getChildren(Object element) {
 		if (manager != null) {
 			Object[] children = manager.getChildren(element);
-			if (children != null)
+			if (children != null) {
+				// This will be a placeholder to indicate 
+				// that the real children are being fetched
 				return children;
+			}
 		}
-		return super.getChildren(element);
+		Object[] children = super.getChildren(element);
+		for (int i = 0; i < children.length; i++) {
+			Object object = children[i];
+			if (object instanceof CVSModelElement) 
+				((CVSModelElement)object).setWorkingSet(getWorkingSet());
+		}
+		return children;
+	}
+
+	public void cancelJobs(RepositoryRoot[] roots) {
+		if (manager != null) {
+			for (int i = 0; i < roots.length; i++) {
+				RepositoryRoot root = roots[i];
+				cancelJobs(root.getRoot());
+			}
+		}
+	}
+	
+	/**
+	 * Cancel any jobs that are fetching content from the given location.
+	 * @param location
+	 */
+	public void cancelJobs(ICVSRepositoryLocation location) {
+		manager.cancel(location);
 	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java
index 17b95ab..18f5520 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteFolderElement.java
@@ -10,22 +10,26 @@
  *******************************************************************************/
 
 package org.eclipse.team.internal.ccvs.ui.model;
+import java.lang.reflect.InvocationTargetException;
+
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jface.progress.IElementCollector;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.team.core.TeamException;
+import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
+import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
 import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
 import org.eclipse.team.internal.ccvs.ui.Policy;
+import org.eclipse.team.internal.ccvs.ui.operations.FetchMembersOperation;
 import org.eclipse.ui.ISharedImages;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
 
-public class RemoteFolderElement extends RemoteResourceElement implements IDeferredWorkbenchAdapter{
-
+public class RemoteFolderElement extends RemoteResourceElement implements IDeferredWorkbenchAdapter {
 
     /**
      * Overridden to append the version name to remote folders which
@@ -61,22 +65,36 @@
     }
 
     public void fetchDeferredChildren(Object o, IElementCollector collector, IProgressMonitor monitor) {
+    	// If it's not a folder, return an empty array
+		if (!(o instanceof ICVSRemoteFolder)) {
+			collector.add(new Object[0], monitor);
+		}
         try {
             monitor = Policy.monitorFor(monitor);
             monitor.beginTask(Policy.bind("RemoteFolderElement.fetchingRemoteChildren", getLabel(o)), 100); //$NON-NLS-1$
-            collector.add(fetchChildren(o, Policy.subMonitorFor(monitor, 90)), Policy.subMonitorFor(monitor, 10));
-        } catch (TeamException e) {
-            CVSUIPlugin.log(e);
-        } finally {
+			FetchMembersOperation operation = new FetchMembersOperation(null, (ICVSRemoteFolder)o, collector);
+			operation.run(Policy.subMonitorFor(monitor, 100));
+        } catch (InvocationTargetException e) {
+			CVSUIPlugin.log(CVSException.wrapException(e));
+		} catch (InterruptedException e) {
+			// Cancelled by the user;
+		} finally {
             monitor.done();
         }
     }
 
-    public ISchedulingRule getRule() {
-        return new BatchSimilarSchedulingRule("org.eclipse.team.ui.cvs.remotefolderelement"); //$NON-NLS-1$
+    public ISchedulingRule getRule(Object element) {
+    	ICVSRepositoryLocation location = getRepositoryLocation(element);
+        return new RepositoryLocationSchedulingRule(location); //$NON-NLS-1$
     }
 
-    public boolean isContainer() {
+	private ICVSRepositoryLocation getRepositoryLocation(Object o) {
+		if (!(o instanceof ICVSRemoteFolder))
+			return null;
+		return ((ICVSRemoteFolder)o).getRepository();
+	}
+
+	public boolean isContainer() {
         return true;
     }
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteModule.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteModule.java
index e381d2c..db9a1e6 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteModule.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RemoteModule.java
@@ -146,7 +146,7 @@
   return true;
  }
 
- public ISchedulingRule getRule() {
-  return new BatchSimilarSchedulingRule("org.eclipse.team.ui.cvs.remotemodule"); //$NON-NLS-1$
+ public ISchedulingRule getRule(Object element) {
+  return new RepositoryLocationSchedulingRule(folder.getRepository()); //$NON-NLS-1$
  }
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/VersionCategory.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/VersionCategory.java
index 5a94751..f18977a 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/VersionCategory.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/VersionCategory.java
@@ -169,7 +169,7 @@
   return true;
  }
 
- public ISchedulingRule getRule() {
-  return new BatchSimilarSchedulingRule("org.eclipse.team.cvs.ui.versioncategory"); //$NON-NLS-1$
+ public ISchedulingRule getRule(Object element) {
+  return new RepositoryLocationSchedulingRule(repository); //$NON-NLS-1$
  }
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java
index 3b60cea..f73de1e 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSOperation.java
@@ -14,28 +14,22 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.core.resources.WorkspaceJob;
-import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableContext;
 import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.CVSStatus;
+import org.eclipse.team.internal.ccvs.core.util.Assert;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
 import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
 import org.eclipse.team.internal.ccvs.ui.Policy;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
 
 
 /**
@@ -50,91 +44,21 @@
 
 	private List errors = new ArrayList(); // of IStatus
 
-	protected static final IStatus OK = new CVSStatus(IStatus.OK, Policy.bind("ok")); //$NON-NLS-1$
+	protected static final IStatus OK = Status.OK_STATUS; //$NON-NLS-1$
 	
-	private IRunnableContext runnableContext;
+	// shell to be used if the runnabl context is a blocking context
 	private Shell shell;
-	private boolean interruptable = true;
 	private boolean modifiesWorkspace = true;
 	
 	// instance variable used to indicate behavior while prompting for overwrite
 	private boolean confirmOverwrite = true;
 	
-	// instance variable used to indicate that the operation is running in the background
-	private boolean runningAsJob = false;
+	ICVSRunnableContext cvsRunnableContext;
 	
-	public static void run(Shell shell, CVSOperation operation) throws CVSException, InterruptedException {
-		operation.setShell(shell);
-		operation.setRunnableContext(new ProgressMonitorDialog(shell));
-		operation.run();
-	}
-	
-	/**
-	 * @param shell
-	 */
 	public CVSOperation(Shell shell) {
 		this.shell = shell;
 	}
-	
-	/**
-	 * Execute the operation in the given runnable context. If null is passed, 
-	 * the runnable context assigned to the operation is used.
-	 * 
-	 * @throws InterruptedException
-	 * @throws CVSException
-	 */
-	public void runInContext(IRunnableContext aRunnableContext) throws InterruptedException, CVSException {
-		if (aRunnableContext == null) {
-			aRunnableContext = getRunnableContext();
-		}
-		try {
-			aRunnableContext.run(isInterruptable(), isInterruptable(), this);
-		} catch (InvocationTargetException e) {
-			throw CVSException.wrapException(e);
-		} catch (OperationCanceledException e) {
-			throw new InterruptedException();
-		}
-	}
-	
-	protected void runAsJob() {
-		Job job;
-		if (isModifiesWorkspace()) {
-			job = getWorkspaceJob();
-		} else {
-			job = getBasicJob();
-		}
-		runningAsJob = true;
-		job.schedule();
-	}
-	
-	protected IStatus runInJob(IProgressMonitor monitor) {
-		try {
-			// Don't wrap inside the run since the WorkspaceJob will do the batching
-			CVSOperation.this.run(monitor, false /* wrap in ModifyOperation*/);
-			return Status.OK_STATUS;
-		} catch (InvocationTargetException e) {
-			return CVSException.wrapException(e).getStatus();
-		} catch (InterruptedException e) {
-			return Status.CANCEL_STATUS;
-		}
-	}
-	
-	protected Job getBasicJob() {
-		return new Job(Policy.bind("CVSOperation.operationJobName", getTaskName())) { //$NON-NLS-1$
-			public IStatus run(IProgressMonitor monitor) {
-				return CVSOperation.this.runInJob(monitor);
-			}
-		};
-	}
-	
-	protected Job getWorkspaceJob() {
-		return new WorkspaceJob(Policy.bind("CVSOperation.operationJobName", getTaskName())) { //$NON-NLS-1$
-			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
-				return CVSOperation.this.runInJob(monitor);
-			}
-		};
-	}
-	
+
 	/**
 	 * Run the operation. Progress feedback will be provided by one of the following mechanisms
 	 * (in priotiry order):
@@ -147,46 +71,64 @@
 	 * @throws InterruptedException
 	 */
 	public synchronized void run() throws CVSException, InterruptedException {
-		if(canRunAsJob() && !hasRunnableContext() && areJobsEnabled()) {
-			runAsJob();
-		} else {
-			runInContext(getRunnableContext());
+		ICVSRunnableContext context = getCVSRunnableContext();
+		try {
+			getCVSRunnableContext().run(getTaskName(), getSchedulingRule(), getPostponeBuild(), this);
+		} catch (InvocationTargetException e) {
+			throw CVSException.wrapException(e);
+		} catch (OperationCanceledException e) {
+			throw new InterruptedException();
 		}
 	}
-	
+
 	protected boolean areJobsEnabled() {
 		return CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.BACKGROUND_OPERATIONS);
 	}
 
 	/**
-	 * Returns true if the operation can be run as a background job
+	 * Returns true if the operation can be run as a background job.
+	 * The default is to support running as a job. Subclass should override
+	 * to prevent background execution of the operation.
 	 * @return whether operation can be run as a job
 	 */
 	public boolean canRunAsJob() {
-		return false;
+		return true;
+	}
+	
+	/**
+	 * Return the scheduling rule that defines the scope of the whole operation.
+	 * This method must either return <code>null</code> (in which case, code executed
+	 * by the operation can attempt to obtain any scheduling rules they like but may be
+	 * blocked by other jobs at that point) or a rule (e.g. IResource) that encompasses
+	 * all scheduling rules used by code nested in the operation (in which case the
+	 * operation wil not start until the encompassing rule is free but once the
+	 * operation starts, nested rules will not block on any subsequent contained 
+	 * scheduling rules). By default, <code>null</code> is returned.
+	 * @return
+	 */
+	protected ISchedulingRule getSchedulingRule() {
+		return null;
+	}
+	
+	/**
+	 * Return whether the auto-build should be postponed whil ethe operation is running.
+	 * The default is to postone a build.
+	 * @return
+	 */
+	protected boolean getPostponeBuild() {
+		return true;
 	}
 	
 	/* (non-Javadoc)
 	 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
 	 */
 	public final void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-		run(monitor, isModifiesWorkspace());
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	private void run(IProgressMonitor monitor, boolean wrapInModifiyOperation) throws InvocationTargetException, InterruptedException {
 		startOperation();
 		try {
-			if (wrapInModifiyOperation) {
-				new CVSWorkspaceModifyOperation(this).run(monitor);
-			} else {
-				execute(monitor);
-			}
+			execute(monitor);
 			endOperation();
 		} catch (CVSException e) {
-			// TODO: errors may not be empty
+			// TODO: errors may not be empty (i.e. endOperation has not been executed)
 			throw new InvocationTargetException(e);
 		}
 	}
@@ -202,67 +144,42 @@
 	}
 
 	/**
-	 * Subclasses must override to perform the operation
+	 * Subclasses must override this method to perform the operation.
+	 * Clients should never call this method directly.
+	 * 
 	 * @param monitor
 	 * @throws CVSException
 	 * @throws InterruptedException
 	 */
-	public abstract void execute(IProgressMonitor monitor) throws CVSException, InterruptedException;
+	protected abstract void execute(IProgressMonitor monitor) throws CVSException, InterruptedException;
 
-	/**
-	 * @return
+	/*
+	 * Return the ICVSRunnableContext which will be used to run the operation.
 	 */
-	private IRunnableContext getRunnableContext() {
-		if (runnableContext == null) {
-			return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+	private ICVSRunnableContext getCVSRunnableContext() {
+		if (cvsRunnableContext == null) {
+			if (canRunAsJob() && areJobsEnabled()) {
+				return new CVSNonblockingRunnableContext();
+			} else {
+				return new CVSBlockingRunnableContext(shell);
+			}
 		}
-		return runnableContext;
+		return cvsRunnableContext;
 	}
-
+	
 	/**
-	 * @param context
+	 * Set the CVS runnable context to be used by the operation.
+	 * Although this method can be used by clients, it's main
+	 * purpose is to support the running of headless operations
+	 * for testing purposes.
+	 * @param cvsRunnableContext
 	 */
-	public void setRunnableContext(IRunnableContext context) {
-		this.runnableContext = context;
-	}
-
-	public boolean hasRunnableContext() {
-		return runnableContext != null;
+	public void setCVSRunnableContext(ICVSRunnableContext cvsRunnableContext) {
+		this.cvsRunnableContext = cvsRunnableContext;
 	}
 	
 	public Shell getShell() {
-		if (isRunningAsJob()) {
-			// We can't use the assigned shell as it may have been disposed
-			// run in syncExec because callback is from an operation,
-			// which is probably not running in the UI thread.
-			final Shell[] newShell = new Shell[] { null };
-			Display.getDefault().syncExec(
-				new Runnable() {
-					public void run() {
-						IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-						if (window == null) {
-							Display display = Display.getDefault();
-							newShell[0] = new Shell(display);
-						} else {
-							newShell[0] = window.getShell();
-						}
-					}
-				});
-			return newShell[0];
-		}
-		return shell;
-	}
-
-	public void setShell(Shell shell) {
-		this.shell = shell;
-	}
-	
-	public boolean isInterruptable() {
-		return interruptable;
-	}
-	
-	public void setInterruptable(boolean b) {
-		interruptable = b;
+		return getCVSRunnableContext().getShell();
 	}
 
 	public boolean isModifiesWorkspace() {
@@ -275,16 +192,39 @@
 
 	protected void addError(IStatus status) {
 		if (status.isOK()) return;
+		if (isLastError(status)) return;
 		errors.add(status);
 	}
-	
+
 	protected void collectStatus(IStatus status)  {
+		if (isLastError(status)) return;
 		statusCount++;
 		if (!status.isOK()) addError(status);
 	}
 	
 	protected void resetErrors() {
 		errors.clear();
+		statusCount = 0;
+	}
+	
+	/**
+	 * Get the last error taht occured. This can be useful when a method
+	 * has a return type but wants to signal an error. The method in question
+	 * can add the error using <code>addError(IStatus)</code> and return null.
+	 * The caller can then query the error using this method. Also, <code>addError(IStatus)</code>
+	 * will not add the error if it is already on the end of the list (using identity comparison)
+	 * which allows the caller to still perform a <code>collectStatus(IStatus)</code>
+	 * to get a valid operation count.
+	 * @return
+	 */
+	protected IStatus getLastError() {
+		Assert.isTrue(errors.size() > 0);
+		IStatus status = (IStatus)errors.get(errors.size() - 1);
+		return status;
+	}
+	
+	private boolean isLastError(IStatus status) {
+		return (errors.size() > 0 && getLastError() == status);
 	}
 	
 	protected void handleErrors(IStatus[] errors) throws CVSException {
@@ -306,7 +246,7 @@
 	}
 
 	protected String getErrorMessage(IStatus[] failures, int totalOperations) {
-		return "Errors occured in " + failures.length + " of " + totalOperations + " operations.";
+		return Policy.bind("CVSOperation.0", String.valueOf(failures.length),  String.valueOf(totalOperations)); //$NON-NLS-1$
 	}
 
 	/**
@@ -380,9 +320,5 @@
 	 * @return
 	 */
 	protected abstract String getTaskName();
-	
-	protected boolean isRunningAsJob() {
-		return runningAsJob;
-	}
 
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSWorkspaceModifyOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSWorkspaceModifyOperation.java
deleted file mode 100644
index df4b794..0000000
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSWorkspaceModifyOperation.java
+++ /dev/null
@@ -1,43 +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.ui.operations;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.ui.actions.WorkspaceModifyOperation;
-
-/**
- * This class wraps a CVSOperation in a workspace modify operation.
- * 
- */
-public class CVSWorkspaceModifyOperation extends WorkspaceModifyOperation {
-
-	private CVSOperation operation;
-	
-	public CVSWorkspaceModifyOperation(CVSOperation operation) {
-		super();
-		this.operation = operation;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.actions.WorkspaceModifyOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	synchronized protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
-		try {
-			operation.execute(monitor);
-		} catch (CVSException e) {
-			throw new InvocationTargetException(e);
-		}
-	}
-}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutIntoOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutIntoOperation.java
index 0bac821..27d518c 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutIntoOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutIntoOperation.java
@@ -22,6 +22,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.core.RepositoryProvider;
 import org.eclipse.team.core.TeamException;
@@ -106,18 +108,27 @@
 	}
 	
 	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutOperation#checkout(org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	protected IStatus checkout(ICVSRemoteFolder folder, IProgressMonitor monitor) throws CVSException {
+		return checkout(folder, getLocalFolder(), isRecursive(), monitor);
+	}
+	
+	/* (non-Javadoc)
 	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutOperation#checkout(org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder[], org.eclipse.core.runtime.IProgressMonitor)
 	 */
 	protected void checkout(ICVSRemoteFolder[] folders, IProgressMonitor monitor) throws CVSException {
-		ICVSFolder parentLocalFolder = getLocalFolder();
-		boolean recurse = isRecursive();
-		monitor.beginTask(null, 100 * folders.length + 100);
-		for (int i = 0; i < folders.length; i++) {
-			ICVSRemoteFolder folder = folders[i];
-			checkout(folders[i], parentLocalFolder, recurse, Policy.subMonitorFor(monitor, 100));
+		monitor.beginTask(null, 100);
+		ISchedulingRule rule = getSchedulingRule();
+		try {
+			//	Obtain a scheduling rule on the projects were about to overwrite
+			Platform.getJobManager().beginRule(rule);
+			super.checkout(folders, Policy.subMonitorFor(monitor, 90));
+			refreshRoot(getLocalRoot(getLocalFolder()), Policy.subMonitorFor(monitor, 10));
+		} finally {
+			Platform.getJobManager().endRule(rule);
+			monitor.done();
 		}
-		refreshRoot(getLocalRoot(parentLocalFolder), Policy.subMonitorFor(monitor, 100));
-		monitor.done();
 	}
 	
 	/*
@@ -311,18 +322,19 @@
 		return OK;
 	}
 
-	private void checkout(final ICVSRemoteFolder remoteFolder, ICVSFolder parentFolder, boolean recurse, IProgressMonitor monitor) throws CVSException {
+	private IStatus checkout(final ICVSRemoteFolder remoteFolder, ICVSFolder parentFolder, boolean recurse, IProgressMonitor monitor) throws CVSException {
 		// Open a connection session to the repository
+		monitor.beginTask(null, 100);
 		ICVSRepositoryLocation repository = remoteFolder.getRepository();
 		Session session = new Session(repository, parentFolder);
 		try {
-			session.open(Policy.subMonitorFor(monitor, 10));
+			session.open(Policy.subMonitorFor(monitor, 5), false /* read-only */);
 			
 			// Determine which local folders will be affected
-			ICVSFolder[] targetFolders = prepareLocalFolders(session, remoteFolder, parentFolder, localFolderName, Policy.subMonitorFor(monitor, 10));
+			ICVSFolder[] targetFolders = prepareLocalFolders(session, remoteFolder, parentFolder, localFolderName, Policy.subMonitorFor(monitor, 5));
 			if (targetFolders == null) {
 				// an error occured and has been added to the operation's error list
-				return;
+				return getLastError();
 			}
 			
 			// Add recurse option
@@ -350,14 +362,15 @@
 				(LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]),
 				new String[] { remoteFolder.getRepositoryRelativePath() },
 				null,
-				Policy.subMonitorFor(monitor, 10));
+				Policy.subMonitorFor(monitor, 80));
 			if (!status.isOK()) {
-				addError(status);
-				return;
+				return status;
 			}
 			
 			manageFolders(targetFolders, repository.getLocation());
 			
+			return OK;
+			
 		} finally {
 			session.close();
 		}
@@ -406,4 +419,18 @@
 	public String getName() {
 		return getTaskName();
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getSchedulingRule()
+	 */
+	protected ISchedulingRule getSchedulingRule() {
+		try {
+			// Use the project of the target folder as the scheduling rule
+			return getLocalFolder().getIResource().getProject();
+		} catch (CVSException e) {
+			CVSUIPlugin.log(e);
+			return null;
+		}
+	}
+
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutMultipleProjectsOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutMultipleProjectsOperation.java
index 3cab1de..b840b10 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutMultipleProjectsOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutMultipleProjectsOperation.java
@@ -12,9 +12,11 @@
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
-import org.eclipse.team.internal.ccvs.ui.Policy;
 
 /**
  * This operation checks out a multiple remote folders into the workspace.
@@ -42,17 +44,12 @@
 		if (targetLocation == null) return null;
 		return targetLocation.append(project.getName());
 	}
-	
-	protected String getTaskName() {
-		ICVSRemoteFolder[] remoteFolders = getRemoteFolders();
-		return Policy.bind("CheckoutMultipleProjectsOperation.taskName", new Integer(remoteFolders.length).toString());  //$NON-NLS-1$
-	}
-	
+
 	/* (non-Javadoc)
-	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutProjectOperation#getTargetProjects(org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder[])
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutOperation#checkout(org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder, org.eclipse.core.runtime.IProgressMonitor)
 	 */
-	protected IProject[] getTargetProjects(ICVSRemoteFolder[] folders) {
-		return null;
+	protected IStatus checkout(ICVSRemoteFolder folder, IProgressMonitor monitor) throws CVSException {
+		return checkout(folder, null, monitor);
 	}
 	
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutOperation.java
index fc27bd4..3b19f2c 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutOperation.java
@@ -11,6 +11,7 @@
 package org.eclipse.team.internal.ccvs.ui.operations;
 
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
@@ -26,9 +27,27 @@
 	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
 	 */
 	public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
-		String taskName = getTaskName();
-		monitor.beginTask(taskName, 100);
-		checkout(getRemoteFolders(), Policy.subMonitorFor(monitor, 100));
+		ICVSRemoteFolder[] folders = getRemoteFolders();
+		checkout(folders, monitor);
+	}
+	
+	/**
+	 * This method invokes <code>checkout(ICVSRemoteFolder, IProgressMonitor)</code>
+	 * for each remote folder of the operation.
+	 * @param folders the remote folders for the operation
+	 * @param monitor the progress monitor
+	 * @throws CVSException if an error occured that should prevent the remaining
+	 * folders from being checked out
+	 */
+	protected void checkout(ICVSRemoteFolder[] folders, IProgressMonitor monitor) throws CVSException {
+		monitor.beginTask(null, folders.length * 100);
+		for (int i = 0; i < folders.length; i++) {
+			ICVSRemoteFolder folder = folders[i];
+			IStatus result = checkout(folder, Policy.subMonitorFor(monitor, 100));
+			collectStatus(result);
+			Policy.checkCanceled(monitor);
+		}
+		monitor.done();
 	}
 
 	protected ICVSRemoteFolder[] getRemoteFolders() {
@@ -40,7 +59,7 @@
 	 * @param folders
 	 * @param monitor
 	 */
-	protected abstract void checkout(ICVSRemoteFolder[] folders, IProgressMonitor monitor)  throws CVSException;
+	protected abstract IStatus checkout(ICVSRemoteFolder folder, IProgressMonitor monitor)  throws CVSException;
 	
 	/* (non-Javadoc)
 	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#canRunAsJob()
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutProjectOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutProjectOperation.java
index 4724af8..3d2c3a9 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutProjectOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutProjectOperation.java
@@ -26,6 +26,9 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.MultiRule;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.core.RepositoryProvider;
 import org.eclipse.team.core.TeamException;
@@ -37,7 +40,6 @@
 import org.eclipse.team.internal.ccvs.core.ICVSFolder;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
 import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
-import org.eclipse.team.internal.ccvs.core.ICVSRunnable;
 import org.eclipse.team.internal.ccvs.core.client.Checkout;
 import org.eclipse.team.internal.ccvs.core.client.Command;
 import org.eclipse.team.internal.ccvs.core.client.Request;
@@ -46,7 +48,6 @@
 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
 import org.eclipse.team.internal.ccvs.ui.Policy;
-
 /**
  * This class acts as an abstract class for checkout operations.
  * It provides a few common methods.
@@ -63,27 +64,6 @@
 		super(shell, remoteFolders);
 		this.targetLocation = targetLocation;
 	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public void runInContext(IProgressMonitor monitor) throws CVSException, InterruptedException {
-		String taskName = getTaskName();
-		monitor.beginTask(taskName, 100);
-		monitor.setTaskName(taskName);
-		checkout(getRemoteFolders(), getTargetProjects(getRemoteFolders()), Policy.subMonitorFor(monitor, 100));
-	}
-	
-	/**
-	 * @return
-	 */
-	protected IProject[] getTargetProjects(ICVSRemoteFolder[] folders) {
-		IProject[] projects = new IProject[folders.length];
-		for (int i = 0; i < projects.length; i++) {
-			projects[i] = ResourcesPlugin.getWorkspace().getRoot().getProject(folders[i].getName());
-		}
-		return projects;
-	}
 	
 	/**
 	 * Create and open the project, using a custom location if there is one.
@@ -137,32 +117,6 @@
 		if (targetLocation == null) return null;
 		return new Path(targetLocation);
 	}
-	
-	/**
-	 * Checkout the remote resources into the local workspace. Each resource will 
-	 * be checked out into the corresponding project. If the corresponding project is
-	 * null or if projects is null, the name of the remote resource is used as the name of the project.
-	 * 
-	 * Resources existing in the local file system at the target project location but now 
-	 * known to the workbench will be overwritten.
-	 */
-	protected void checkout(ICVSRemoteFolder[] resources, IProject[] projects, IProgressMonitor pm) throws CVSException {
-		try {
-			pm.beginTask(null, 1000 * resources.length);
-			for (int i=0;i<resources.length;i++) {
-				ICVSRemoteFolder resource = resources[i];
-				
-				// Determine the provided target project if there is one
-				IProject project = null;
-				if (projects != null) 
-					project = projects[i];
-				
-				checkout(resource, project, Policy.subMonitorFor(pm, 1000));
-			}
-		} finally {
-			pm.done();
-		}
-	}
 
 	protected String getRemoteModuleName(ICVSRemoteFolder resource) {
 		String moduleName;
@@ -174,26 +128,85 @@
 		return moduleName;
 	}
 
-	protected void checkout(ICVSRemoteFolder resource, IProject project, final IProgressMonitor pm) throws CVSException {
-		// Get the location of the workspace root
+	protected IStatus checkout(ICVSRemoteFolder resource, IProject project, IProgressMonitor pm) throws CVSException {
+		// Get the location and the workspace root
 		ICVSFolder root = CVSWorkspaceRoot.getCVSFolderFor(ResourcesPlugin.getWorkspace().getRoot());
-		// Open a connection session to the repository
 		ICVSRepositoryLocation repository = resource.getRepository();
+		// Open a connection session to the repository
 		Session session = new Session(repository, root);
+		pm.beginTask(null, 100);
+		session.open(Policy.subMonitorFor(pm, 5), false /* read-only */);
 		try {
-			pm.beginTask(null, 1000);
-			session.open(Policy.subMonitorFor(pm, 50));
 			
-			// Determine the local target projects (either the project provider or the module expansions) 
-			IProject[] targetProjects = prepareProjects(session, resource, project, Policy.subMonitorFor(pm, 50));
-			if (targetProjects == null) return;
-			
-			// Determine if the target project is the same name as the remote folder
-			// in which case we'll use -d to flatten the directory structure
-			if (targetProjects.length == 1 && targetProjects[0].getName().equals(resource.getName())) {
-				project = targetProjects[0];
+			// Determine the local target projects (either the project provider or the module expansions)
+			// Note: Module expansions can be run over the same connection as a checkout
+			IProject[] targetProjects = determineProjects(session, resource, project, Policy.subMonitorFor(pm, 5));
+			if (targetProjects == null) {
+				// An error occurred and was recorded so return it
+				return getLastError();
+			} else if (targetProjects.length == 0) {
+				return OK;
 			}
 		
+			ISchedulingRule rule = getSchedulingRule(targetProjects);
+			try {
+				//	Obtain a scheduling rule on the projects were about to overwrite
+				Platform.getJobManager().beginRule(rule);
+				IStatus result = performCheckout(session, resource, targetProjects, project != null, Policy.subMonitorFor(pm, 90));
+				return result;
+			} finally {
+				Platform.getJobManager().endRule(rule);
+			}
+		} catch (CVSException e) {
+			// An exception occurred either during the module-expansion or checkout
+			// Since we were able to make a connection, return the status so the
+			// checkout of any other modules can proceed
+			return e.getStatus();
+		} finally {
+			session.close();
+			pm.done();
+		}
+	}
+
+	private ISchedulingRule getSchedulingRule(IProject[] projects) {
+		if (projects.length == 1) {
+			return projects[0];
+		} else {
+			return new MultiRule(projects);
+		}
+	}
+
+	private IStatus performCheckout(Session session, ICVSRemoteFolder resource, IProject[] targetProjects, boolean sendModuleName, IProgressMonitor pm) throws CVSException {
+		// Set the task name of the progress monitor to let the user know
+		// which project we're on. Don't use subTask since that will be
+		// changed when the checkout command is run.
+		String taskName;
+		if (targetProjects.length == 1) {
+			taskName = Policy.bind("CheckoutProjectOperation.8", resource.getName(), targetProjects[0].getName()); //$NON-NLS-1$
+		} else {
+			taskName = Policy.bind("CheckoutProjectOperation.9", resource.getName(), String.valueOf(targetProjects.length)); //$NON-NLS-1$
+		}
+		pm.beginTask(taskName, 100);
+		pm.setTaskName(taskName);
+		
+		try {
+			// Scrub the local contents if requested
+			if (performScrubProjects()) {
+				IStatus result = scrubProjects(resource, targetProjects, Policy.subMonitorFor(pm, 9));
+				if (!result.isOK()) {
+					return result;
+				}
+			}
+				
+			// Determine if the target project is the same name as the remote folder
+			// in which case we'll use -d to flatten the directory structure
+			IProject project;
+			if (targetProjects.length == 1 && (sendModuleName || targetProjects[0].getName().equals(resource.getName()))) {
+				project = targetProjects[0];
+			} else {
+				project = null;
+			}
+				
 			// Build the local options
 			List localOptions = new ArrayList();
 			// Add the option to load into the target project if one was supplied
@@ -210,48 +223,46 @@
 				tag = CVSTag.DEFAULT;
 			}
 			localOptions.add(Update.makeTagOption(tag));
-		
+			
 			// Perform the checkout
 			IStatus status = Command.CHECKOUT.execute(session,
 				Command.NO_GLOBAL_OPTIONS,
 				(LocalOption[])localOptions.toArray(new LocalOption[localOptions.size()]),
 				new String[]{getRemoteModuleName(resource)},
 				null,
-				Policy.subMonitorFor(pm, 800));
+				Policy.subMonitorFor(pm, 90));
 			if (status.getCode() == CVSStatus.SERVER_ERROR) {
-				// TODO: Should we cleanup any partially checked out projects?
-				signalFailure(status);
-				return;
+				// Any created projects will exist but will not be mapped to CVS
+				return status;
 			}
-			
+				
 			// Bring the project into the workspace
-			refreshProjects(targetProjects, Policy.subMonitorFor(pm, 100));
-		
+			refreshProjects(targetProjects, Policy.subMonitorFor(pm, 1));
+			
+			return OK;
 		} finally {
-			session.close();
 			pm.done();
 		}
 	}
 
 	/*
-	 * Prepare the workspace to receive the project(s). If project is not null, then
-	 * if will be the only target project of the checkout. Otherwise, the remote folder
-	 * could expand to multiple projects.
+	 * Determine the workspace project(s) that will be affected by the checkout. 
+	 * If project is not null, then it will be the only target project of the checkout. 
+	 * Otherwise, the remote folder could expand to multiple projects.
 	 * 
 	 * If the remote resource is a folder which is not a root folder (i.e. a/b/c),
 	 * then the target project will be the last segment (i.e. c).
 	 */
-	private IProject[] prepareProjects(Session session, final ICVSRemoteFolder remoteFolder, IProject project, IProgressMonitor pm) throws CVSException {
+	private IProject[] determineProjects(Session session, final ICVSRemoteFolder remoteFolder, IProject project, IProgressMonitor pm) throws CVSException {
 			
-		pm.beginTask(null, 100);
 		Set targetProjectSet = new HashSet();
 		String moduleName = getRemoteModuleName(remoteFolder);
 		if (project == null) {
 			
 			// Fetch the module expansions
-			IStatus status = Request.EXPAND_MODULES.execute(session, new String[] {moduleName}, Policy.subMonitorFor(pm, 50));
+			IStatus status = Request.EXPAND_MODULES.execute(session, new String[] {moduleName}, pm);
 			if (status.getCode() == CVSStatus.SERVER_ERROR) {
-				signalFailure(status);
+				collectStatus(status);
 				return null;
 			}
 			
@@ -271,36 +282,24 @@
 			targetProjectSet.add(project);
 		}
 		
-		final IProject[] targetProjects = (IProject[]) targetProjectSet.toArray(new IProject[targetProjectSet.size()]);
-		// Prepare the target projects to receive resources
-		// TODO: Does this really need to be wrapped or is it done higher up?
-		final IStatus[] result = new IStatus[] { null };
-		session.getLocalRoot().run(new ICVSRunnable() {
-			public void run(IProgressMonitor monitor) throws CVSException {
-				try {
-					result[0] = scrubProjects(remoteFolder, targetProjects, monitor);
-				} catch (InterruptedException e) {
-					// The operation was cancelled. The result wiull be null
-				}
-			}
-		}, Policy.subMonitorFor(pm, 50));
-		pm.done();
-		// return the target projects if the scrub succeeded
-		if (result[0] == null) {
-			return null;
-		} else if (result[0].isOK()) {
-			return targetProjects;
-		} else {
-			signalFailure(result[0]);
-			return null;
-		}
+		// Return the local projects affected by the checkout
+		IProject[] targetProjects = (IProject[]) targetProjectSet.toArray(new IProject[targetProjectSet.size()]);
+		return targetProjects;
+	}
+
+	/**
+	 * Return true if the target projects should be scrubbed before the checkout occurs.
+	 * Default is to scrub the projects. Can be overridden by subclasses.
+	 */
+	protected boolean performScrubProjects() {
+		return true;
 	}
 
 	/*
 	 * This method is invoked to scrub the local projects that are the check out target of
 	 * a single remote module.
 	 */
-	private IStatus scrubProjects(ICVSRemoteFolder remoteFolder, IProject[] projects, IProgressMonitor monitor) throws CVSException, InterruptedException {
+	private IStatus scrubProjects(ICVSRemoteFolder remoteFolder, IProject[] projects, IProgressMonitor monitor) throws CVSException {
 		if (projects == null) {
 			monitor.done();
 			return OK;
@@ -312,7 +311,7 @@
 		for (int i=0;i<projects.length;i++) {
 			IProject project = projects[i];
 			if (needsPromptForOverwrite(project) && !promptToOverwrite(remoteFolder, project)) {
-				throw new InterruptedException();
+				Policy.cancelOperation();
 			}
 		}
 		// Create the projects and remove any previous content
@@ -415,19 +414,14 @@
 			monitor.done();
 		}
 	}
-	
-	/**
-	 * @param status
-	 */
-	private void signalFailure(IStatus status) {
-		// TODO: count failures so a count of successes can be displayed at the end
-		addError(status);
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutOperation#checkout(org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder[], org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	protected void checkout(ICVSRemoteFolder[] folders, IProgressMonitor monitor) throws CVSException {
-		checkout(folders, getTargetProjects(folders), monitor);
-	}
 
+	protected String getTaskName() {
+		ICVSRemoteFolder[] remoteFolders = getRemoteFolders();
+		if (remoteFolders.length == 1) {
+			return Policy.bind("CheckoutSingleProjectOperation.taskname", remoteFolders[0].getName()); //$NON-NLS-1$
+		} else {
+			return Policy.bind("CheckoutMultipleProjectsOperation.taskName", new Integer(remoteFolders.length).toString());  //$NON-NLS-1$
+		}
+	}
+	
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutSingleProjectOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutSingleProjectOperation.java
index bbef990..50ff902 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutSingleProjectOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CheckoutSingleProjectOperation.java
@@ -11,9 +11,11 @@
 package org.eclipse.team.internal.ccvs.ui.operations;
 
 import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;
-import org.eclipse.team.internal.ccvs.ui.Policy;
 
 /**
  * This operation checks out a single remote folder into the workspace as
@@ -22,7 +24,6 @@
 public class CheckoutSingleProjectOperation extends CheckoutProjectOperation {
 
 	private boolean preconfigured;
-	private ICVSRemoteFolder remoteFolder;
 	private IProject targetProject;
 	
 	public CheckoutSingleProjectOperation(Shell shell, ICVSRemoteFolder remoteFolder, IProject targetProject, String targetLocation, boolean preconfigured) {
@@ -30,17 +31,7 @@
 		this.targetProject = targetProject;
 		this.preconfigured = preconfigured;
 	}
-	
-	/**
-	 * @return
-	 */
-	private String getRemoteFolderName() {
-		return getRemoteFolders()[0].getName();
-	}
 
-	/**
-	 * @return
-	 */
 	private boolean isPreconfigured() {
 		return preconfigured;
 	}
@@ -55,17 +46,18 @@
 	}
 
 	/* (non-Javadoc)
-	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName()
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutProjectOperation#performScrubProjects()
 	 */
-	protected String getTaskName() {
-		return Policy.bind("CheckoutSingleProjectOperation.taskname", getRemoteFolderName(), targetProject.getName()); //$NON-NLS-1$
+	protected boolean performScrubProjects() {
+		// Do not scrub the projects if they were preconfigured.
+		return !isPreconfigured();
 	}
-	
+
 	/* (non-Javadoc)
-	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutOperation#getTargetProjects(org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder[])
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CheckoutOperation#checkout(org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder, org.eclipse.core.runtime.IProgressMonitor)
 	 */
-	protected IProject[] getTargetProjects(ICVSRemoteFolder[] remoteFolders) {
-		return new IProject[] { targetProject };
+	protected IStatus checkout(ICVSRemoteFolder folder, IProgressMonitor monitor) throws CVSException {
+		return checkout(folder, targetProject, monitor);
 	}
 
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/HasProjectMetaFileOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/HasProjectMetaFileOperation.java
index 9626964..20df10c 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/HasProjectMetaFileOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/HasProjectMetaFileOperation.java
@@ -11,7 +11,6 @@
 package org.eclipse.team.internal.ccvs.ui.operations;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableContext;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.core.TeamException;
 import org.eclipse.team.internal.ccvs.core.CVSException;
@@ -28,11 +27,8 @@
 	private ICVSRemoteFolder remoteFolder;
 	private boolean metaFileExists;
 	
-	public static boolean hasMetaFile(Shell shell, ICVSRemoteFolder remoteFolder, IRunnableContext runnableContext) throws CVSException, InterruptedException {
+	public static boolean hasMetaFile(Shell shell, ICVSRemoteFolder remoteFolder) throws CVSException, InterruptedException {
 		HasProjectMetaFileOperation op = new HasProjectMetaFileOperation(shell, remoteFolder);
-		if (runnableContext != null) {
-			op.setRunnableContext(runnableContext);
-		}
 		op.run();
 		return op.metaFileExists();
 	}
@@ -49,7 +45,7 @@
 	private boolean hasMetaFile(ICVSRemoteFolder folder, IProgressMonitor monitor) throws CVSException {
 		
 		// make a copy of the folder so that we will not effect the original folder when we refetch the members
-		// TODO: this is a strang thing to need to do. We shold fix this.
+		// TODO: this is a strange thing to need to do. We shold fix this.
 		folder = (ICVSRemoteFolder)folder.forTag(remoteFolder.getTag());
 
 		try {
@@ -91,6 +87,15 @@
 	}
 
 	protected String getTaskName() {
-		return Policy.bind("HasProjectMetaFile.taskName");
+		return Policy.bind("HasProjectMetaFile.taskName"); //$NON-NLS-1$
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#canRunAsJob()
+	 */
+	public boolean canRunAsJob() {
+		// This operation should never be run in the background.
+		return false;
+	}
+
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/RepositoryProviderOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/RepositoryProviderOperation.java
index d0fbb86..5b8f071 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/RepositoryProviderOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/RepositoryProviderOperation.java
@@ -53,8 +53,7 @@
 	public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
 		Map table = getProviderMapping(getResources());
 		Set keySet = table.keySet();
-		monitor.beginTask("", keySet.size() * 1000);
-		monitor.setTaskName(getTaskName());
+		monitor.beginTask(null, keySet.size() * 1000);
 		Iterator iterator = keySet.iterator();
 		while (iterator.hasNext()) {
 			IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1000);
@@ -99,13 +98,6 @@
 	protected void setResources(IResource[] resources) {
 		this.resources = resources;
 	}
-	
-	/**
-	 * Return the task name associated with the operation. This task name
-	 * will appear in progress feedback presented to the user.
-	 * @return
-	 */
-	protected abstract String getTaskName();
 
 	/**
 	 * Execute the operation on the resources for the given provider.
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/SingleCommandOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/SingleCommandOperation.java
index 4ee9d2e..de2f9a8 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/SingleCommandOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/SingleCommandOperation.java
@@ -39,7 +39,7 @@
 	protected void execute(CVSTeamProvider provider, IResource[] resources, IProgressMonitor monitor) throws CVSException, InterruptedException {
 		monitor.beginTask(null, 100);
 		Session session = new Session(getRemoteLocation(provider), getLocalRoot(provider), true /* output to console */);
-		session.open(Policy.subMonitorFor(monitor, 10));
+		session.open(Policy.subMonitorFor(monitor, 10), isServerModificationOperation());
 		try {
 			IStatus status = executeCommand(session, provider, resources, Policy.subMonitorFor(monitor, 90));
 			if (status.getCode() == CVSStatus.SERVER_ERROR) {
@@ -51,6 +51,15 @@
 	}
 
 	/**
+	 * Indicate whether the operation requires write access to the server (i.e.
+	 * the operation changes state on the server whether it be to commit, tag, admin, etc).
+	 * @return
+	 */
+	protected boolean isServerModificationOperation() {
+		return false;
+	}
+
+	/**
 	 * Method overridden by subclasses to issue the command to the CVS repository using the given session.
 	 */
 	protected abstract IStatus executeCommand(Session session, CVSTeamProvider provider, IResource[] resources, IProgressMonitor monitor) throws CVSException, InterruptedException;
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagInRepositoryOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagInRepositoryOperation.java
index 1b1faea..4035e0e 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagInRepositoryOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagInRepositoryOperation.java
@@ -100,6 +100,6 @@
 	}
 
 	protected String getTaskName() {
-		return Policy.bind("TagFromRepository.taskName");
+		return Policy.bind("TagFromRepository.taskName"); //$NON-NLS-1$
 	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagOperation.java
index 13f9651..459bd06 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/TagOperation.java
@@ -89,7 +89,7 @@
 		progress.beginTask(null, 100);
 		try {
 			// Opening the session takes 20% of the time
-			s.open(Policy.subMonitorFor(progress, 20));
+			s.open(Policy.subMonitorFor(progress, 20), true /* open for modification */);
 			return Command.TAG.execute(s,
 				Command.NO_GLOBAL_OPTIONS,
 				commandOptions,
@@ -122,6 +122,6 @@
 	}
 
 	protected  String getTaskName() {
-		return Policy.bind("TagFromWorkspace.taskName");
+		return Policy.bind("TagFromWorkspace.taskName"); //$NON-NLS-1$
 	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOnlyMergableOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOnlyMergableOperation.java
index a869a10..cfecbfc 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOnlyMergableOperation.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/UpdateOnlyMergableOperation.java
@@ -62,7 +62,7 @@
 	 * @see org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation#getTaskName()
 	 */
 	protected String getTaskName() {
-		return Policy.bind("UpdateOnlyMergeable.taskName");
+		return Policy.bind("UpdateOnlyMergeable.taskName"); //$NON-NLS-1$
 	}
 
 	protected void addSkippedFiles(IFile[] files) {
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java
index d5d083f..e1ec233 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java
@@ -22,6 +22,8 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -62,19 +64,18 @@
 	
 	boolean passwordChanged;
 	boolean connectionInfoChanged;
-	boolean programNameChanged;
-	boolean labelChanged;
 
 	IUserInfo info;
 
-	// Program Name
-	private Text programNameText;
-	private Button useDefaultProgramName;
-	private Button useCustomProgramName;
 	// Label
 	private Button useLocationAsLabel;
 	private Button useCustomLabel;
 	private Text labelText;
+	// Read/write access
+	private Button useDefaultReadWriteLocations;
+	private Button useCustomReadWriteLocations;
+	private Combo readLocation;
+	private Combo writeLocation;
 			
 	/*
 	 * @see PreferencesPage#createContents
@@ -101,7 +102,6 @@
 		labelGroup.setLayout(layout);
 		Listener labelListener = new Listener() {
 			public void handleEvent(Event event) {
-				labelChanged = true;
 				updateWidgetEnablements();
 			}
 		};
@@ -114,50 +114,32 @@
 		// Add some extra space
 		createLabel(composite, "", 3); //$NON-NLS-1$
 		
-		Label label = createLabel(composite, Policy.bind("CVSPropertiesPage.connectionType"), 1); //$NON-NLS-1$
+		createLabel(composite, Policy.bind("CVSPropertiesPage.connectionType"), 1); //$NON-NLS-1$
 		methodType = createCombo(composite);
 		
-		label = createLabel(composite, Policy.bind("CVSPropertiesPage.user"), 1); //$NON-NLS-1$
+		createLabel(composite, Policy.bind("CVSPropertiesPage.user"), 1); //$NON-NLS-1$
 		userText = createTextField(composite);
 		
-		label = createLabel(composite, Policy.bind("CVSPropertiesPage.password"), 1); //$NON-NLS-1$
+		createLabel(composite, Policy.bind("CVSPropertiesPage.password"), 1); //$NON-NLS-1$
 		passwordText = createPasswordField(composite);
 			
-		label = createLabel(composite, Policy.bind("CVSPropertiesPage.host"), 1); //$NON-NLS-1$
+		createLabel(composite, Policy.bind("CVSPropertiesPage.host"), 1); //$NON-NLS-1$
 		hostLabel = createLabel(composite, "", 2); //$NON-NLS-1$
 		
-		label = createLabel(composite, Policy.bind("CVSPropertiesPage.port"), 1); //$NON-NLS-1$
+		createLabel(composite, Policy.bind("CVSPropertiesPage.port"), 1); //$NON-NLS-1$
 		portLabel = createLabel(composite, "", 2); //$NON-NLS-1$
 		
-		label = createLabel(composite, Policy.bind("CVSPropertiesPage.path"), 1); //$NON-NLS-1$
+		createLabel(composite, Policy.bind("CVSPropertiesPage.path"), 1); //$NON-NLS-1$
 		pathLabel = createLabel(composite, "", 2); //$NON-NLS-1$
 
 		// Add some extra space
 		createLabel(composite, "", 3); //$NON-NLS-1$
 
-		// Remote CVS program name
-		// create a composite to ensure the radio buttons come in the correct order
-		Composite programNameGroup = new Composite(composite, SWT.NONE);
-		data = new GridData();
-		data.horizontalSpan = 3;
-		programNameGroup.setLayoutData(data);
-		layout = new GridLayout();
-		layout.numColumns = 3;
-		layout.marginHeight = 0;
-		layout.marginWidth = 0;
-		programNameGroup.setLayout(layout);
-		Listener programNameListener = new Listener() {
-			public void handleEvent(Event event) {
-				programNameChanged = true;
-				updateWidgetEnablements();
-			}
-		};
-		useDefaultProgramName = createRadioButton(programNameGroup, Policy.bind("CVSRepositoryPropertiesPage.useDefaultProgramName"), 3); //$NON-NLS-1$
-		useCustomProgramName = createRadioButton(programNameGroup, Policy.bind("CVSRepositoryPropertiesPage.useProgramName"), 1); //$NON-NLS-1$
-		useCustomProgramName.addListener(SWT.Selection, programNameListener);
-		programNameText = createTextField(programNameGroup);
-		programNameText.addListener(SWT.Modify, programNameListener);
-				
+		// Add some extra space
+		createLabel(composite, "", 3); //$NON-NLS-1$
+		
+		createReadWriteAccessComposite(composite);
+		
 		initializeValues();
 		updateWidgetEnablements();
 		passwordText.addListener(SWT.Modify, new Listener() {
@@ -175,10 +157,51 @@
 				connectionInfoChanged = true;
 			}
 		});
+		useDefaultReadWriteLocations.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				updateWidgetEnablements();
+
+			}
+		});
+		useCustomReadWriteLocations.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				updateWidgetEnablements();
+	
+			}
+		});
+		
 		WorkbenchHelp.setHelp(getControl(), IHelpContextIds.REPOSITORY_LOCATION_PROPERTY_PAGE);
 		return composite;
 	}
 	/**
+	 * @param composite
+	 */
+	private void createReadWriteAccessComposite(Composite composite) {
+		Composite radioGroup = createRadioGroupComposite(composite);
+		useDefaultReadWriteLocations = createRadioButton(radioGroup, "Use this location's connection information for all connections", 3);
+		useCustomReadWriteLocations = createRadioButton(radioGroup, "Use the following locations for read and write access", 3);
+		createLabel(composite, "Read:", 1);
+		readLocation = createCombo(composite);
+		createLabel(composite, "Write:", 1);
+		writeLocation = createCombo(composite);
+	}
+	/**
+	 * @param composite
+	 */
+	private Composite createRadioGroupComposite(Composite composite) {
+		Composite radioGroup = new Composite(composite, SWT.NONE);
+		GridData data = new GridData();
+		data.horizontalSpan = 3;
+		radioGroup.setLayoutData(data);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 3;
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		radioGroup.setLayout(layout);
+		return radioGroup;
+	}
+	
+	/**
 	 * Utility method that creates a combo box
 	 *
 	 * @param parent  the parent for the new label
@@ -300,12 +323,6 @@
 		}
 		pathLabel.setText(location.getRootDirectory());
 		
-		// get the program name
-		String programName = ((CVSRepositoryLocation)location).getRemoteCVSProgramName();
-		programNameText.setText(programName);
-		useDefaultProgramName.setSelection(programName == CVSRepositoryLocation.DEFAULT_REMOTE_CVS_PROGRAM_NAME);
-		useCustomProgramName.setSelection(!useDefaultProgramName.getSelection());
-		
 		// get the repository label
 		String label = null;
 		RepositoryRoot root = CVSUIPlugin.getPlugin().getRepositoryManager().getRepositoryRootFor(location);
@@ -316,47 +333,67 @@
 			label = location.getLocation();
 		}
 		labelText.setText(label);
+		
+		// Fill in read/write repo locations
+		String currentReadLocation = ((CVSRepositoryLocation)root.getRoot()).getReadLocation();
+		String currentWriteLocation = ((CVSRepositoryLocation)root.getRoot()).getWriteLocation();
+		try {
+			// Ensure the read and write locations are listed
+			if (currentReadLocation != null) {
+				CVSProviderPlugin.getPlugin().getRepository(currentReadLocation);
+			}
+			if (currentWriteLocation != null) {
+				CVSProviderPlugin.getPlugin().getRepository(currentWriteLocation);
+			}
+		} catch (CVSException e) {
+			CVSProviderPlugin.log(e);
+		}
+
+		ICVSRepositoryLocation[] locations = CVSProviderPlugin.getPlugin().getKnownRepositories();
+		for (int i = 0; i < locations.length; i++) {
+			ICVSRepositoryLocation location = locations[i];
+			readLocation.add(location.getLocation());
+			writeLocation.add(location.getLocation());
+		}
+		readLocation.setText(currentReadLocation == null ? root.getRoot().getLocation() : currentReadLocation);
+		writeLocation.setText(currentWriteLocation == null ? root.getRoot().getLocation() : currentWriteLocation);
+		if (currentReadLocation == null && currentWriteLocation == null) {
+			useDefaultReadWriteLocations.setSelection(true);
+			useCustomReadWriteLocations.setSelection(false);
+		} else {
+			useDefaultReadWriteLocations.setSelection(false);
+			useCustomReadWriteLocations.setSelection(true);
+		}
 	}
 	
-	/*
-	 * @see PreferencesPage#performOk
-	 */
-	public boolean performOk() {
-		if (!connectionInfoChanged && !passwordChanged) {
-			if (programNameChanged) {
-				recordNewProgramName((CVSRepositoryLocation)location);
-			}
-			if (labelChanged) {
-				recordNewLabel((CVSRepositoryLocation)location);
-			}
-			return true;
-		}
-		info.setUsername(userText.getText());
-		if (passwordChanged) {
-			info.setPassword(passwordText.getText());
-		}
-		final String type = methodType.getText();
-		final String password = passwordText.getText();
-		final boolean[] result = new boolean[] { false };
+	private boolean performConnectionInfoChanges() {
+		// Don't do anything if there wasn't a password or connection change
+		if (!passwordChanged && !connectionInfoChanged) return true;
+		
 		try {
+			// Check if the password was the only thing to change.
+			if (passwordChanged && !connectionInfoChanged) {
+				CVSRepositoryLocation oldLocation = (CVSRepositoryLocation)location;
+				oldLocation.setPassword(getNewPassword());
+				oldLocation.updateCache();
+				passwordChanged = false;
+				return true;
+			}
+		
+			// Otherwise change the connection info and the password
 			// This operation is done inside a workspace operation in case the sharing
 			// info for existing projects is changed
+			final boolean[] result = new boolean[] { false };
 			new ProgressMonitorDialog(getShell()).run(false, false, new WorkspaceModifyOperation() {
 				public void execute(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
 					try {
-						// Check if the password was the only thing to change.
-						if (passwordChanged && !connectionInfoChanged) {
-							CVSRepositoryLocation oldLocation = (CVSRepositoryLocation)location;
-							oldLocation.setPassword(password);
-							oldLocation.updateCache();
-							passwordChanged = false;
-							result[0] = true;
-							return;
-						}
-						
 						// Create a new repository location with the new information
 						CVSRepositoryLocation newLocation = CVSRepositoryLocation.fromString(location.getLocation());
-						newLocation.setMethod(type);
+						newLocation.setMethod(methodType.getText());
+						info.setUsername(userText.getText());
+						if (passwordChanged) {
+							info.setPassword(getNewPassword());
+						}
 						newLocation.setUserInfo(info);
 						
 						try {
@@ -410,32 +447,39 @@
 							newLocation.updateCache();
 						}
 						
-						
 						// Set the location of the page to the new location in case Apply was chosen
 						location = newLocation;
-						
-						if (programNameChanged) {
-							recordNewProgramName((CVSRepositoryLocation)location);
-						}
-						if (labelChanged) {
-							recordNewLabel((CVSRepositoryLocation)location);
-						}
-			
 						connectionInfoChanged = false;
 						passwordChanged = false;
-						programNameChanged = false;
 					} catch (TeamException e) {
 						throw new InvocationTargetException(e);
 					}
 					result[0] = true;
 				}
 			});
+			return result[0];
 		} catch (InvocationTargetException e) {
 			handle(e);
 		} catch (InterruptedException e) {
+		} catch (CVSException e) {
+			handle(e);
 		}
-					
-		return result[0];
+		return false; /* we only get here if an exception occurred */
+	}
+	
+	private void performNonConnectionInfoChanges() {
+		recordNewLabel((CVSRepositoryLocation)location);
+		recordReadWriteLocations((CVSRepositoryLocation)location);
+	}
+	/*
+	 * @see PreferencesPage#performOk
+	 */
+	public boolean performOk() {
+		if (performConnectionInfoChanges()) {
+			performNonConnectionInfoChanges();
+			return true;
+		}
+		return false;
 	}
 	/**
 	 * Shows the given errors to the user.
@@ -448,26 +492,22 @@
 	 * Updates widget enablements and sets error message if appropriate.
 	 */
 	protected void updateWidgetEnablements() {
-		if (useDefaultProgramName.getSelection()) {
-			programNameText.setEnabled(false);
-		} else {
-			programNameText.setEnabled(true);
-		}
 		if (useLocationAsLabel.getSelection()) {
 			labelText.setEnabled(false);
 		} else {
 			labelText.setEnabled(true);
 		}
+		if (useDefaultReadWriteLocations.getSelection()) {
+			readLocation.setEnabled(false);
+			writeLocation.setEnabled(false);
+		} else {
+			readLocation.setEnabled(true);
+			writeLocation.setEnabled(true);
+		}
 		validateFields();
 	}
 	
 	private void validateFields() {
-		if (programNameText.isEnabled()) {
-			if (programNameText.getText().length() == 0) {
-				setValid(false);
-				return;
-			}
-		}
 		if (labelText.isEnabled()) {
 			if (labelText.getText().length() == 0) {
 				setValid(false);
@@ -477,20 +517,26 @@
 		setValid(true);
 	}
 	
-	private void recordNewProgramName(CVSRepositoryLocation location) {
-		// Set the remote program name if appropriate
-		String newProgramName;
-		if (useDefaultProgramName.getSelection()) {
-			newProgramName = CVSRepositoryLocation.DEFAULT_REMOTE_CVS_PROGRAM_NAME;
-		} else {
-			newProgramName = programNameText.getText();
+	private void recordNewLabel(CVSRepositoryLocation location) {
+		String newLabel = getNewLabel(location);
+		if (newLabel == null) {
+			String oldLabel = getOldLabel(location);
+			if (oldLabel == null || oldLabel.equals(location.getLocation())) {
+				return;
+			}
+		} else if (newLabel.equals(getOldLabel(location))) {
+			return;
 		}
-		if (!location.getRemoteCVSProgramName().equals(newProgramName)) {
-			CVSProviderPlugin.getPlugin().setCVSProgramName(location, newProgramName);
+		try {
+			CVSUIPlugin.getPlugin().getRepositoryManager().setLabel(location, newLabel);
+		} catch (CVSException e) {
+			CVSUIPlugin.log(e);
 		}
 	}
-	
-	private void recordNewLabel(CVSRepositoryLocation location) {
+	private String getOldLabel(CVSRepositoryLocation location) {
+		return CVSUIPlugin.getPlugin().getRepositoryManager().getRepositoryRootFor(location).getName();
+	}
+	private String getNewLabel(CVSRepositoryLocation location) {
 		String label = null;
 		if (useCustomLabel.getSelection()) {
 			label = labelText.getText();
@@ -498,11 +544,15 @@
 				label = null;
 			}
 		}
-		try {
-			CVSUIPlugin.getPlugin().getRepositoryManager().setLabel(location, label);
-		} catch (CVSException e) {
-			CVSUIPlugin.log(e);
-		}
+		return label;
+	}
+	/* internal use only */ String getNewPassword() {
+		return passwordText.getText();
+	}
+	private void recordReadWriteLocations(CVSRepositoryLocation location) {
+		location.setReadLocation(useDefaultReadWriteLocations.getSelection() ? null : readLocation.getText());
+		location.setWriteLocation(useDefaultReadWriteLocations.getSelection() ? null : writeLocation.getText());
+		// TODO: These will be lost if a crash occurres before shutdown
 	}
 }
 
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoteViewPart.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoteViewPart.java
index 4313af5..15227fd 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoteViewPart.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoteViewPart.java
@@ -367,7 +367,7 @@
 
 	protected void refreshViewer() {
 		if (viewer == null) return;
-		//((RemoteContentProvider)viewer.getContentProvider()).clearCache();
+		((RemoteContentProvider)viewer.getContentProvider()).cancelJobs(CVSUIPlugin.getPlugin().getRepositoryManager().getKnownRepositoryRoots());
 		CVSUIPlugin.getPlugin().getRepositoryManager().purgeCache();
 		updateWorkingSetMenu();
 		viewer.refresh();
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java
index 954501a..6a1b436 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RemoveRootAction.java
@@ -13,8 +13,10 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 
+import org.eclipse.core.internal.jobs.JobManager;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.core.RepositoryProvider;
@@ -24,6 +26,7 @@
 import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
 import org.eclipse.team.internal.ccvs.ui.Policy;
 import org.eclipse.team.internal.ccvs.ui.actions.CVSAction;
+import org.eclipse.team.internal.ccvs.ui.model.RepositoryLocationSchedulingRule;
 import org.eclipse.team.internal.ui.dialogs.DetailsDialogWithProjects;
 import org.eclipse.ui.actions.SelectionListenerAction;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
@@ -34,10 +37,12 @@
  */
 public class RemoveRootAction extends SelectionListenerAction {
 	private IStructuredSelection selection;
-	private Shell shell;
+	/* internal use only */ Shell shell;
+	private RepositoriesView view;
 	
-	public RemoveRootAction(Shell shell) {
+	public RemoveRootAction(Shell shell, RepositoriesView view) {
 		super(Policy.bind("RemoteRootAction.label")); //$NON-NLS-1$
+		this.view = view;
 		this.shell = shell;
 	}
 	
@@ -104,7 +109,14 @@
 						}
 					});
 				} else {
-					provider.disposeRepository(roots[i]);
+					ISchedulingRule rule = new RepositoryLocationSchedulingRule(roots[i]);
+					JobManager.getInstance().beginRule(rule);
+					try {
+						view.getContentProvider().cancelJobs(roots[i]);
+						provider.disposeRepository(roots[i]);
+					} finally {
+						JobManager.getInstance().endRule(rule);
+					}
 				}
 			} catch (CVSException e) {
 				CVSUIPlugin.log(e);
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java
index 505993b..6ab0637 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesView.java
@@ -155,7 +155,7 @@
 				propertiesAction.setEnabled(enabled);
 			}
 		});
-		removeRootAction = new RemoveRootAction(viewer.getControl().getShell());
+		removeRootAction = new RemoveRootAction(viewer.getControl().getShell(), this);
 		removeRootAction.selectionChanged((IStructuredSelection)null);
 		WorkbenchHelp.setHelp(removeRootAction, IHelpContextIds.REMOVE_REPOSITORY_LOCATION_ACTION);
 		IActionBars bars = getViewSite().getActionBars();
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesViewContentHandler.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesViewContentHandler.java
index ff6ffd4..d40b0cf 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesViewContentHandler.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoriesViewContentHandler.java
@@ -19,6 +19,7 @@
 import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
 import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
+import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
 import org.eclipse.team.internal.ccvs.ui.Policy;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -40,7 +41,8 @@
 	public static final String PATH_ATTRIBUTE = "path"; //$NON-NLS-1$
 	public static final String FULL_PATH_ATTRIBUTE = "full-path"; //$NON-NLS-1$
 	public static final String TYPE_ATTRIBUTE = "type"; //$NON-NLS-1$
-	public static final String REPOSITORY_PROGRAM_NAME_ATTRIBUTE = "program-name"; //$NON-NLS-1$
+	public static final String READ_ID_ATTRIBUTE = "read-id"; //$NON-NLS-1$
+	public static final String WRITE_ID_ATTRIBUTE = "write-id"; //$NON-NLS-1$
 	
 	public static final String[] TAG_TYPES = {"head", "branch", "version", "date"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 	public static final String DEFAULT_TAG_TYPE = "version"; //$NON-NLS-1$
@@ -127,6 +129,10 @@
 			if (name != null) {
 				currentRepositoryRoot.setName(name);
 			}
+			String readLocation = atts.getValue(READ_ID_ATTRIBUTE);
+			((CVSRepositoryLocation)root).setReadLocation(readLocation);
+			String writeLocation = atts.getValue(WRITE_ID_ATTRIBUTE);
+			((CVSRepositoryLocation)root).setWriteLocation(writeLocation);
 		} else if (localName.equals(WORKING_SET_TAG)) {
 			String name = atts.getValue(NAME_ATTRIBUTE);
 			if (name == null) {
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java
index 778a7fd..8782220 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryManager.java
@@ -213,7 +213,7 @@
 	public ICVSRemoteResource[] getFoldersForTag(ICVSRepositoryLocation location, CVSTag tag, IProgressMonitor monitor) throws CVSException {		
 		monitor = Policy.monitorFor(monitor);
 		try {
-			monitor.beginTask(Policy.bind("RepositoryManager.fetchingRemoteFolders", tag.getName()), 100);
+			monitor.beginTask(Policy.bind("RepositoryManager.fetchingRemoteFolders", tag.getName()), 100); //$NON-NLS-1$
 			if (tag.getType() == CVSTag.HEAD) {
 				ICVSRemoteResource[] resources = location.members(tag, false, Policy.subMonitorFor(monitor, 60));
 				RepositoryRoot root = getRepositoryRootFor(location);
@@ -909,7 +909,10 @@
 						CVSProviderPlugin.getPlugin().disposeRepository(oldLocation);
 						
 						newLocation.updateCache();
-						root.setRepositoryLocation(newLocation);
+						// Get the new location from the CVS plugin to ensure we use the
+						// instance that will be returned by future calls to getRepository()
+						root.setRepositoryLocation(
+							CVSProviderPlugin.getPlugin().getRepository(newLocation.getLocation()));
 						add(root);
 					} catch (CVSException e) {
 						throw new InvocationTargetException(e);
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java
index 3da9241..c78467b 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java
@@ -338,13 +338,18 @@
 
 		attributes.clear();
 		attributes.put(RepositoriesViewContentHandler.ID_ATTRIBUTE, root.getLocation());
-		String programName = ((CVSRepositoryLocation)root).getRemoteCVSProgramName();
-		if (!programName.equals(CVSRepositoryLocation.DEFAULT_REMOTE_CVS_PROGRAM_NAME)) {
-			attributes.put(RepositoriesViewContentHandler.REPOSITORY_PROGRAM_NAME_ATTRIBUTE, programName);
-		}
 		if (name != null) {
 			attributes.put(RepositoriesViewContentHandler.NAME_ATTRIBUTE, name);
 		}
+		String readLocation = ((CVSRepositoryLocation)root).getReadLocation();
+		if (readLocation != null) {
+			attributes.put(RepositoriesViewContentHandler.READ_ID_ATTRIBUTE, readLocation);
+		}
+		String writeLocation = ((CVSRepositoryLocation)root).getWriteLocation();
+		if (writeLocation != null) {
+			attributes.put(RepositoriesViewContentHandler.WRITE_ID_ATTRIBUTE, writeLocation);
+		}
+		
 		writer.startTag(RepositoriesViewContentHandler.REPOSITORY_TAG, attributes, true);
 		
 		// Gather all the modules that have tags and/or auto-refresh files
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java
index 8b39aff..c962b4f 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSSubscriberAction.java
@@ -12,14 +12,18 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+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.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.MultiRule;
 import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.operation.IRunnableContext;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.team.core.TeamException;
 import org.eclipse.team.core.subscribers.SyncInfo;
@@ -31,10 +35,13 @@
 import org.eclipse.team.internal.ccvs.core.client.PruneFolderVisitor;
 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
+import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
 import org.eclipse.team.internal.ccvs.ui.Policy;
+import org.eclipse.team.internal.ccvs.ui.operations.CVSBlockingRunnableContext;
+import org.eclipse.team.internal.ccvs.ui.operations.CVSSubscriberNonblockingContext;
+import org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext;
 import org.eclipse.team.ui.sync.SubscriberAction;
 import org.eclipse.team.ui.sync.SyncInfoSet;
-import org.eclipse.ui.PlatformUI;
 
 public abstract class CVSSubscriberAction extends SubscriberAction {
 	
@@ -117,7 +124,7 @@
 		SyncInfoSet syncSet = getFilteredSyncInfoSet(getFilteredSyncInfos());
 		if (syncSet == null || syncSet.isEmpty()) return;
 		try {
-			getRunnableContext().run(true /* fork */, true /* cancelable */, getRunnable(syncSet));
+			getCVSRunnableContext().run(getJobName(syncSet), getSchedulingRule(syncSet), true, getRunnable(syncSet));
 		} catch (InvocationTargetException e) {
 			handle(e);
 		} catch (InterruptedException e) {
@@ -156,10 +163,58 @@
 
 	protected abstract void run(SyncInfoSet syncSet, IProgressMonitor monitor) throws TeamException;
 
-	protected IRunnableContext getRunnableContext() {
-		return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+	/*
+	 * Return the ICVSRunnableContext which will be used to run the operation.
+	 */
+	private ICVSRunnableContext getCVSRunnableContext() {
+		if (canRunAsJob() && areJobsEnabled()) {
+			return new CVSSubscriberNonblockingContext();
+		} else {
+			return new CVSBlockingRunnableContext(shell);
+		}
 	}
 	
+	protected boolean areJobsEnabled() {
+		return CVSUIPlugin.getPlugin().getPreferenceStore().getBoolean(ICVSUIConstants.BACKGROUND_OPERATIONS);
+	}
+	
+	/**
+	 * Return the job name to be used if the action can run as a job.
+	 * 
+	 * @param syncSet
+	 * @return
+	 */
+	protected String getJobName(SyncInfoSet syncSet) {
+		return Policy.bind("CVSSubscriberAction.jobName", new Integer(syncSet.size()).toString()); //$NON-NLS-1$
+	}
+
+	/**
+	 * Return a scheduling rule that includes all resources that will be operated 
+	 * on by the subscriber action. The default behavior is to include all projects
+	 * effected by the operation. Subclasses may override.
+	 * 
+	 * @param syncSet
+	 * @return
+	 */
+	protected ISchedulingRule getSchedulingRule(SyncInfoSet syncSet) {
+		IResource[] resources = syncSet.getResources();
+		Set set = new HashSet();
+		for (int i = 0; i < resources.length; i++) {
+			IResource resource = resources[i];
+			set.add(resource.getProject());
+		}
+		IProject[] projects = (IProject[]) set.toArray(new IProject[set.size()]);
+		if (projects.length == 1) {
+			return projects[0];
+		} else {
+			return new MultiRule(projects);
+		}
+	}
+
+	protected boolean canRunAsJob() {
+		return true;
+	}
+
 	/**
 	 * Filter the sync resource set using action specific criteria or input from the user.
 	 */
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java
index 4b39895..c636104 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/MergeUpdateAction.java
@@ -42,6 +42,8 @@
  */
 public class MergeUpdateAction extends SafeUpdateAction {
 	
+	TeamSubscriber currentSubcriber = null;
+	
 	/* (non-Javadoc)
 	 * @see org.eclipse.team.internal.ccvs.ui.subscriber.SafeUpdateAction#getOverwriteLocalChanges()
 	 */
@@ -54,16 +56,17 @@
 	 */
 	protected SyncInfoFilter getSyncInfoFilter() {
 		// Update works for all incoming and conflicting nodes
-		// TODO: there should be an instance variable for the filter
 		return new OrSyncInfoFilter(new SyncInfoFilter[] {
 			new SyncInfoDirectionFilter(SyncInfo.INCOMING),
 			new SyncInfoDirectionFilter(SyncInfo.CONFLICTING)
 		});
 	}
 	
-	protected void updated(IResource[] resources) throws CVSException {
+	protected void updated(IResource[] resources) throws TeamException {
 		// Mark all succesfully updated resources as merged
-		((CVSMergeSubscriber)getSubscriber()).merged(resources);
+		if(resources.length > 0 && currentSubcriber != null) {
+			((CVSMergeSubscriber)currentSubcriber).merged(resources);
+		}
 	}
 	
 	/* (non-Javadoc)
@@ -93,12 +96,13 @@
 	 */
 	protected void runSafeUpdate(SyncInfo[] nodes, IProgressMonitor monitor) throws TeamException {
 		if(nodes.length > 0) {
-			TeamSubscriber subscriber = nodes[0].getSubscriber();
-			if (!(subscriber instanceof CVSMergeSubscriber)) {
-				throw new CVSException("Invalid subscriber: " + subscriber.getId());
+			// Assumption that all nodes are from the same subscriber.
+			currentSubcriber = nodes[0].getSubscriber();
+			if (!(currentSubcriber instanceof CVSMergeSubscriber)) {
+				throw new CVSException(Policy.bind("MergeUpdateAction.invalidSubscriber", currentSubcriber.getId().toString())); //$NON-NLS-1$
 			}
-			CVSTag startTag = ((CVSMergeSubscriber)subscriber).getStartTag();
-			CVSTag endTag = ((CVSMergeSubscriber)subscriber).getEndTag();
+			CVSTag startTag = ((CVSMergeSubscriber)currentSubcriber).getStartTag();
+			CVSTag endTag = ((CVSMergeSubscriber)currentSubcriber).getEndTag();
 
 			// Incoming additions require different handling then incoming changes and deletions
 			List additions = new ArrayList();
@@ -206,4 +210,11 @@
 			cvsFolder.mkdir();
 		}
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction#getJobName(org.eclipse.team.ui.sync.SyncInfoSet)
+	 */
+	protected String getJobName(SyncInfoSet syncSet) {
+		return Policy.bind("MergeUpdateAction.jobName", new Integer(syncSet.size()).toString()); //$NON-NLS-1$
+	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java
index 02b7477..eea80dc 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SafeUpdateAction.java
@@ -333,4 +333,12 @@
 	protected String getErrorTitle() {
 		return Policy.bind("UpdateAction.update"); //$NON-NLS-1$
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction#getJobName(org.eclipse.team.ui.sync.SyncInfoSet)
+	 */
+	protected String getJobName(SyncInfoSet syncSet) {
+		return Policy.bind("UpdateAction.jobName", new Integer(syncSet.size()).toString()); //$NON-NLS-1$
+	}
+
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java
index 344eeb4..ac64849 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberCommitAction.java
@@ -103,12 +103,8 @@
 		return true;
 	}
 	
-	/**
-	 * @param syncSet
-	 * @return
-	 */
 	private IResource[] getUnaddedResources(SyncInfoSet syncSet) throws CVSException {
-		// TODO: should only get outgoing additions (since conflicting additions 
+		// TODO: Should only get outgoing additions (since conflicting additions 
 		// could be considered to be under version control already)
 		IResource[] resources = syncSet.getResources();
 		List result = new ArrayList();
@@ -200,7 +196,6 @@
 						}
 						break;
 					case SyncInfo.CONFLICTING:
-						// TODO: what about conflicting deletions
 						// Convert the conflicting change to an outgoing change
 						makeOutgoing.add(changedNode);
 						break;
@@ -228,9 +223,6 @@
 			if (makeOutgoing.size() > 0) {
 				makeOutgoing((SyncInfo[]) makeOutgoing.toArray(new SyncInfo[makeInSync.size()]), Policy.subMonitorFor(monitor, makeOutgoing.size() * 100));			
 			}
-			
-			// TODO: There was special handling for undoing incoming deletions
-			// This should be handled by makeOutgoing but we'll need to verify
 
 			RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager();
 			if (additions.size() != 0) {
@@ -241,7 +233,6 @@
 			}
 			manager.commit((IResource[])commits.toArray(new IResource[commits.size()]), comment, Policy.subMonitorFor(monitor, commits.size() * 100));
 			
-			// TODO: are there any cases that need to have folders pruned?
 		} catch (TeamException e) {
 			throw CVSException.wrapException(e);
 		}
@@ -287,4 +278,11 @@
 	protected String getErrorTitle() {
 		return Policy.bind("CommitAction.commitFailed"); //$NON-NLS-1$
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.subscriber.CVSSubscriberAction#getJobName(org.eclipse.team.ui.sync.SyncInfoSet)
+	 */
+	protected String getJobName(SyncInfoSet syncSet) {
+		return Policy.bind("CommitAction.jobName", new Integer(syncSet.size()).toString()); //$NON-NLS-1$
+	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java
index 1f07239..c8e0662 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/SubscriberConfirmMergedAction.java
@@ -60,5 +60,10 @@
 		}
 	}
 
+	protected boolean canRunAsJob() {
+		// There's no sense doing this operation in the background since
+		// it does not contact the server
+		return false;
+	}
 
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java
index 9513ff0..6b1445c 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/UpdateDialog.java
@@ -28,7 +28,7 @@
 	public static final int YES = IDialogConstants.YES_ID;
 	
 	public UpdateDialog(Shell parentShell, SyncInfoSet syncSet) {
-		super(parentShell, Policy.bind("UpdateDialog.overwriteTitle"), Policy.bind("UpdateDialog.overwriteDetailsTitle"), syncSet); //$NON-NLS-1$
+		super(parentShell, Policy.bind("UpdateDialog.overwriteTitle"), Policy.bind("UpdateDialog.overwriteDetailsTitle"), syncSet); //$NON-NLS-1$ //$NON-NLS-2$
 	}
 
 	/* (non-Javadoc)
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java
index 0c77162..20b0255 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/CVSCatchupReleaseViewer.java
@@ -62,12 +62,12 @@
 import org.eclipse.team.internal.ccvs.ui.HistoryView;
 import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
 import org.eclipse.team.internal.ccvs.ui.IHelpContextIds;
-import org.eclipse.team.internal.ccvs.ui.OverlayIcon;
 import org.eclipse.team.internal.ccvs.ui.OverlayIconCache;
 import org.eclipse.team.internal.ccvs.ui.Policy;
 import org.eclipse.team.internal.ccvs.ui.merge.OverrideUpdateMergeAction;
 import org.eclipse.team.internal.ccvs.ui.merge.UpdateMergeAction;
 import org.eclipse.team.internal.ccvs.ui.merge.UpdateWithForcedJoinAction;
+import org.eclipse.team.internal.ui.OverlayIcon;
 import org.eclipse.team.internal.ui.sync.CatchupReleaseViewer;
 import org.eclipse.team.internal.ui.sync.ChangedTeamContainer;
 import org.eclipse.team.internal.ui.sync.ITeamNode;
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsLocationSelectionPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsLocationSelectionPage.java
index cceabd7..d8b7080 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsLocationSelectionPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsLocationSelectionPage.java
@@ -43,7 +43,7 @@
  */
 public class CheckoutAsLocationSelectionPage extends CVSWizardPage {
 
-	public static final String NAME = "CheckoutAsLocationSelectionPage";
+	public static final String NAME = "CheckoutAsLocationSelectionPage"; //$NON-NLS-1$
 	
 	private Button browseButton;
 	private Text locationPathField;
@@ -63,7 +63,7 @@
 	 * @param description
 	 */
 	public CheckoutAsLocationSelectionPage(ImageDescriptor titleImage, ICVSRemoteFolder[] remoteFolders) {
-		super(NAME, Policy.bind("CheckoutAsLocationSelectionPage.title"), titleImage, Policy.bind("CheckoutAsLocationSelectionPage.description"));
+		super(NAME, Policy.bind("CheckoutAsLocationSelectionPage.title"), titleImage, Policy.bind("CheckoutAsLocationSelectionPage.description")); //$NON-NLS-1$ //$NON-NLS-2$
 		this.remoteFolders = remoteFolders;
 	}
 
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsMainPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsMainPage.java
index 6d2305e..58e3f2e 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsMainPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsMainPage.java
@@ -45,7 +45,7 @@
 	private Text projectNameField;
 	private ICVSRemoteFolder[] folders;
 
-	public static final String NAME = "CheckoutAsMainPage";
+	public static final String NAME = "CheckoutAsMainPage"; //$NON-NLS-1$
 	
 	/**
 	 * @param pageName
@@ -54,7 +54,7 @@
 	 * @param description
 	 */
 	public CheckoutAsMainPage(ImageDescriptor titleImage, ICVSRemoteFolder[] folders, boolean allowProjectConfiguration) {
-		super(NAME, Policy.bind("CheckoutAsMainPage.title"), titleImage, Policy.bind("CheckoutAsMainPage.description")); //$NON-NLS-1$
+		super(NAME, Policy.bind("CheckoutAsMainPage.title"), titleImage, Policy.bind("CheckoutAsMainPage.description")); //$NON-NLS-1$ //$NON-NLS-2$
 		this.folders = folders;
 		this.allowProjectConfiguration = allowProjectConfiguration;
 	}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsProjectSelectionPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsProjectSelectionPage.java
index 7566de2..9b57d19 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsProjectSelectionPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CheckoutAsProjectSelectionPage.java
@@ -52,7 +52,7 @@
  */
 public class CheckoutAsProjectSelectionPage extends CVSWizardPage {
 	
-	public static final String NAME = "CheckoutAsProjectSelectionPage";
+	public static final String NAME = "CheckoutAsProjectSelectionPage"; //$NON-NLS-1$
 	
 	private TreeViewer tree;
 	private Text nameField;
@@ -73,7 +73,7 @@
 	 * @param titleImage
 	 */
 	public CheckoutAsProjectSelectionPage(ImageDescriptor titleImage, ICVSRemoteFolder[] remoteFolders) {
-		super(NAME, Policy.bind("CheckoutAsProjectSelectionPage.title"), titleImage, Policy.bind("CheckoutAsProjectSelectionPage.description"));
+		super(NAME, Policy.bind("CheckoutAsProjectSelectionPage.title"), titleImage, Policy.bind("CheckoutAsProjectSelectionPage.description")); //$NON-NLS-1$ //$NON-NLS-2$
 		this.remoteFolders = remoteFolders;
 	}
 
@@ -227,7 +227,7 @@
 	}
 			
 	/**
-	 * Method getValidTargetProjects returns the et of projects that match the provided criteria.
+	 * Method getValidTargetProjects returns the set of projects that match the provided criteria.
 	 * @return IResource
 	 */
 	private IProject[] getProjects(String root, boolean unshared) throws CVSException {
@@ -245,7 +245,7 @@
 						} else if (provider != null && provider.getID().equals(CVSProviderPlugin.getTypeId())) {
 							ICVSFolder cvsFolder = CVSWorkspaceRoot.getCVSFolderFor(project);
 							FolderSyncInfo info = cvsFolder.getFolderSyncInfo();
-							if (root != null && root.equals(info.getRoot())) {
+							if (root != null && info != null && root.equals(info.getRoot())) {
 								validTargets.add(project);
 							}
 						}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/RepositorySelectionPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/RepositorySelectionPage.java
index 51c4d1c..120c3ac 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/RepositorySelectionPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/RepositorySelectionPage.java
@@ -62,6 +62,7 @@
 		Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
 		GridData data = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL);
 		data.horizontalSpan = span;
+		data.widthHint = 200;
 		table.setLayoutData(data);
 		TableLayout layout = new TableLayout();
 		layout.addColumnData(new ColumnWeightData(100, true));
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java
index 99e6aed..29527db 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/SharingWizard.java
@@ -303,8 +303,9 @@
 					IWorkingSet workingSet = CVSUIPlugin.getWorkingSet(new IResource[] {project}, Policy.bind("SyncAction.workingSetName")); //$NON-NLS-1$)
 					view.setWorkingSet(workingSet);
 					view.selectSubscriber(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber());
+					view.setMode(ISynchronizeView.OUTGOING_MODE);
 				} else {
-					CVSUIPlugin.openError(getContainer().getShell(), Policy.bind("error"), Policy.bind("Error.unableToShowSyncView"), null);
+					CVSUIPlugin.openError(getContainer().getShell(), Policy.bind("error"), Policy.bind("Error.unableToShowSyncView"), null); //$NON-NLS-1$ //$NON-NLS-2$
 				}
 			}
 		} catch (InterruptedException e) {