This commit was manufactured by cvs2svn to create tag 'R2_1_1'.

Sprout from master 2003-03-27 13:14:38 UTC Andre Weinand <aweinand> 'updated buildnotes'
Cherrypick from R2_1_maintenance 2003-05-27 12:40:26 UTC Michael Valenta <mvalenta> 'Backed out of fix for bug 36351 because pserver is not properly buffering':
    bundles/org.eclipse.team.core/plugin.xml
    bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java
    bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/TimeoutOutputStream.java
    bundles/org.eclipse.team.cvs.core/plugin.xml
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTag.java
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/PServerConnection.java
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MutableResourceSyncInfo.java
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java
    bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
    bundles/org.eclipse.team.cvs.ssh/plugin.xml
    bundles/org.eclipse.team.cvs.ssh/src/org/eclipse/team/internal/ccvs/ssh/Client.java
    bundles/org.eclipse.team.cvs.ui/plugin.xml
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorConfiguration.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFilePropertiesPage.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFolderPropertiesPage.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSLightweightDecorator.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSProjectPropertiesPage.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSPropertiesPage.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ExtMethodPreferencePage.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagConfigurationDialog.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkingSetSelectionArea.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareRemoteWithTagAction.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/CVSRepositoryPropertiesPage.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositoryRoot.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositorySorter.java
    tests/org.eclipse.team.tests.cvs.core/plugin.xml
    tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/IsModifiedTests.java
    tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ResourceDeltaTest.java
diff --git a/bundles/org.eclipse.team.core/plugin.xml b/bundles/org.eclipse.team.core/plugin.xml
index dadb07b..b7f9fc7 100644
--- a/bundles/org.eclipse.team.core/plugin.xml
+++ b/bundles/org.eclipse.team.core/plugin.xml
@@ -3,7 +3,7 @@
 <plugin
    id="org.eclipse.team.core"
    name="%pluginName"
-   version="2.1.0"
+   version="2.1.1"
    provider-name="%providerName"
    class="org.eclipse.team.internal.core.TeamPlugin">
 <requires>
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java
index b0413e3..05b165b 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java
@@ -485,7 +485,11 @@
 					for (int j = 0; j < configElements.length; j++) {
 						String pattern = configElements[j].getAttribute("pattern"); //$NON-NLS-1$
 						if (pattern != null) {
-							String selected = configElements[j].getAttribute("selected"); //$NON-NLS-1$
+							String selected = configElements[j].getAttribute("enabled"); //$NON-NLS-1$
+							if (selected == null) {
+								// Check for selected because this used to be the field name
+								selected = configElements[j].getAttribute("selected"); //$NON-NLS-1$
+							}
 							boolean enabled = selected != null && selected.equalsIgnoreCase("true"); //$NON-NLS-1$
 							// if this ignore doesn't already exist, add it to the global list
 							pluginIgnore.put(pattern, new Boolean(enabled));
diff --git a/bundles/org.eclipse.team.cvs.core/plugin.xml b/bundles/org.eclipse.team.cvs.core/plugin.xml
index 80d3fff..77ed182 100644
--- a/bundles/org.eclipse.team.cvs.core/plugin.xml
+++ b/bundles/org.eclipse.team.cvs.core/plugin.xml
@@ -2,7 +2,7 @@
 <plugin
 	name="%pluginName"
 	id="org.eclipse.team.cvs.core"
-	version="2.1.0"
+	version="2.1.1"
     provider-name="%providerName"
 	class="org.eclipse.team.internal.ccvs.core.CVSProviderPlugin">
 
@@ -53,36 +53,36 @@
  
  	<!-- *************** Resource patterns ignored by CVS **************** -->
  	<extension point="org.eclipse.team.core.ignore">
-		<ignore pattern = "RCS" selected = "true"/>
-		<ignore pattern = "RCSLOG" selected = "true"/>
-		<ignore pattern = "SCCS" selected = "true"/>
-		<ignore pattern = "CVS.adm" selected = "true"/>
-		<ignore pattern = "tags" selected = "true"/>
-		<ignore pattern = "TAGS" selected = "true"/>
-		<ignore pattern = ".make.state" selected = "true"/>
-		<ignore pattern = ".nse_depinfo" selected = "true"/>
-		<ignore pattern = "*~" selected = "true"/>
-		<ignore pattern = "#*" selected = "true"/>
-		<ignore pattern = ".#*" selected = "true"/>
-		<ignore pattern = ",*" selected = "true"/>
-		<ignore pattern = "_$*" selected = "true"/>
-		<ignore pattern = "*$" selected = "true"/>
-		<ignore pattern = "*.old" selected = "true"/>
-		<ignore pattern = "*.bak" selected = "true"/>
-		<ignore pattern = "*.BAK" selected = "true"/>
-		<ignore pattern = "*.orig" selected = "true"/>
-		<ignore pattern = "*.rej" selected = "true"/>
-		<ignore pattern = ".del-*" selected = "true"/>
-		<ignore pattern = "*.a" selected = "true"/>
-		<ignore pattern = "*.olb" selected = "true"/>
-		<ignore pattern = "*.obj" selected = "true"/>
-		<ignore pattern = "*.so" selected = "true"/>
-		<ignore pattern = "*.exe" selected = "true"/>
-		<ignore pattern = "*.Z" selected = "true"/>
-		<ignore pattern = "*.elc" selected = "true"/>
-		<ignore pattern = "*.ln" selected = "true"/>
-		<ignore pattern = ".DS_Store" selected = "true"/>
-		<ignore pattern = "core" selected = "false"/>
+		<ignore pattern = "RCS" enabled = "true"/>
+		<ignore pattern = "RCSLOG" enabled = "true"/>
+		<ignore pattern = "SCCS" enabled = "true"/>
+		<ignore pattern = "CVS.adm" enabled = "true"/>
+		<ignore pattern = "tags" enabled = "true"/>
+		<ignore pattern = "TAGS" enabled = "true"/>
+		<ignore pattern = ".make.state" enabled = "true"/>
+		<ignore pattern = ".nse_depinfo" enabled = "true"/>
+		<ignore pattern = "*~" enabled = "true"/>
+		<ignore pattern = "#*" enabled = "true"/>
+		<ignore pattern = ".#*" enabled = "true"/>
+		<ignore pattern = ",*" enabled = "true"/>
+		<ignore pattern = "_$*" enabled = "true"/>
+		<ignore pattern = "*$" enabled = "true"/>
+		<ignore pattern = "*.old" enabled = "true"/>
+		<ignore pattern = "*.bak" enabled = "true"/>
+		<ignore pattern = "*.BAK" enabled = "true"/>
+		<ignore pattern = "*.orig" enabled = "true"/>
+		<ignore pattern = "*.rej" enabled = "true"/>
+		<ignore pattern = ".del-*" enabled = "true"/>
+		<ignore pattern = "*.a" enabled = "true"/>
+		<ignore pattern = "*.olb" enabled = "true"/>
+		<ignore pattern = "*.obj" enabled = "true"/>
+		<ignore pattern = "*.so" enabled = "true"/>
+		<ignore pattern = "*.exe" enabled = "true"/>
+		<ignore pattern = "*.Z" enabled = "true"/>
+		<ignore pattern = "*.elc" enabled = "true"/>
+		<ignore pattern = "*.ln" enabled = "true"/>
+		<ignore pattern = ".DS_Store" enabled = "true"/>
+		<ignore pattern = "core" enabled = "false"/>
 	</extension>
  
   	<!-- *************** Markers **************** -->
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTag.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTag.java
index af4bb95..2b4b5fd 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTag.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/CVSTag.java
@@ -54,6 +54,7 @@
 	}
 
 	public int getType() {
+		// TODO: getType() will not return accurate types for Tags retrieved from the local CVS Entries file.  See Bug: 36758
 		return type;
 	}
 	
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
index 0eb178a..13918e4 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
@@ -396,6 +396,9 @@
 						// an unedited file is no longer modified
 						setModified(false);
 					}
+				} else {
+					// We still need to report a state change
+					setSyncBytes(getSyncBytes(), ICVSFile.CLEAN);
 				}
 				setBaserevInfo(null);
 					
@@ -430,10 +433,10 @@
 			// The file contents matched the server contents so no entry line was sent
 			if (oldInfo == null) return;
 			Date timeStamp = oldInfo.getTimeStamp();
-			if (timeStamp == null) {
+			if (timeStamp == null || oldInfo.isMergedWithConflicts()) {
 				// If the entry line has no timestamp, put the file timestamp in the entry line
 				MutableResourceSyncInfo mutable = oldInfo.cloneMutable();
-				mutable.setTimeStamp(getTimeStamp());
+				mutable.setTimeStamp(getTimeStamp(), true /* clear merged */);
 				newInfo = mutable;
 			} else {
 				// reset the file timestamp to the one from the entry line
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java
index ecf2c43..10e072a 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseSynchronizer.java
@@ -562,6 +562,24 @@
 	}
 	
 	/**
+	 * The resource has been deleted. Make sure any cached state is cleared.
+	 * This is needed because the move/delete hook is not invoked in all situations
+	 * (e.g. external deletion).
+	 * 
+	 * @param resource
+	 * @throws CVSException
+	 */
+	protected void handleDeleted(IResource resource) throws CVSException {
+		if (resource.exists()) return;
+		try {
+			beginOperation(null);
+			adjustDirtyStateRecursively(resource, RECOMPUTE_INDICATOR);
+		} finally {
+			endOperation(null);
+		}
+	}
+	
+	/**
 	 * Prepare for a move or delete within the move/delete hook by moving the
 	 * sync info into phantom space and flushing the session properties cache.
 	 * This will allow sync info for deletions to be maintained in the source
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java
index f434777..31eead7 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/FileModificationManager.java
@@ -86,8 +86,11 @@
 					} else if (delta.getKind() == IResourceDelta.ADDED) {
 						resourceChanged(resource, true);
 					} else if (delta.getKind() == IResourceDelta.REMOVED) {
-						// provide notifications for deletions since they may not have been managed
-						// The move/delete hook would have updated the parent counts properly
+						try {
+							EclipseSynchronizer.getInstance().handleDeleted(resource);
+						} catch (CVSException e) {
+							CVSProviderPlugin.log(e);
+						}
 						modifiedResources.add(resource);
 					}
 
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MutableResourceSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MutableResourceSyncInfo.java
index e955a3b..caf6948 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MutableResourceSyncInfo.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/MutableResourceSyncInfo.java
@@ -88,6 +88,15 @@
 	}
 	
 	/**
+	 * Sets the timeStamp.
+	 * @param timeStamp The timeStamp to set
+	 */
+	public void setTimeStamp(Date timeStamp, boolean clearMerged) {
+		setTimeStamp(timeStamp);
+		if (clearMerged) setSyncType(TYPE_REGULAR);
+	}
+	
+	/**
 	 * Sets the keywordMode.
 	 * @param keywordMode The keywordMode to set
 	 */
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java
index 066831a..c1c54b7 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/SyncFileChangeListener.java
@@ -24,7 +24,9 @@
 import org.eclipse.core.runtime.Path;
 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.Policy;
+import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
 import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
 
 /*
@@ -122,6 +124,8 @@
 						toBeNotified = handleChangedMetaFile(resource, kind);
 					} else if(name.equals(SyncFileWriter.IGNORE_FILE)) {
 						toBeNotified = handleChangedIgnoreFile(resource, kind);
+					} else if (isExternalDeletion(resource, kind)) {
+						toBeNotified = handleExternalDeletion(resource);
 					}
 										
 					if(toBeNotified.length>0 && isModifiedBy3rdParty(resource)) {
@@ -148,6 +152,45 @@
 		}
 	}
 	
+	/**
+	 * @param resource
+	 * @return
+	 */
+	protected IContainer[] handleExternalDeletion(IResource resource) {
+		IContainer changedContainer = resource.getParent();
+		if(changedContainer.exists()) {
+			return new IContainer[] {changedContainer};
+		} else {
+			return new IContainer[0];
+		}
+	}
+
+	/**
+	 * Treat a resource as an external deletion if 
+	 *   - it is a file 
+	 *   - the delta says the file was removed
+	 *   - the file is not managed but its parent is a CVS folder
+	 * 
+	 * There will be some false positives but the reaction to this situation
+	 * is to purge the cahced CVS meta-information so nothing bad will happen
+	 * for the false positives.
+	 * 
+	 * @param resource
+	 * @param kind
+	 * @return
+	 */
+	protected boolean isExternalDeletion(IResource resource, int kind) {
+		if (kind != IResourceDelta.REMOVED) return false;
+		if (resource.getType() != IResource.FILE) return false;
+		ICVSFile file = CVSWorkspaceRoot.getCVSFileFor((IFile)resource);
+		try {
+			return (!file.isManaged() && file.getParent().isCVSFolder());
+		} catch (CVSException e) {
+			CVSProviderPlugin.log(e);
+			return false;
+		}
+	}
+
 	/*
 	 * Consider non-existing resources as being recently deleted and thus modified, and resources
 	 * with modification stamps that differ from when the CVS plugin last modified the meta-file.
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
index 2a19f16..1191486 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
@@ -18,15 +18,23 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
+import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.core.ICVSFolder;
 import org.eclipse.team.internal.ccvs.core.ICVSResource;
 import org.eclipse.team.internal.ccvs.core.Policy;
 import org.eclipse.team.internal.ccvs.core.client.Session;
+import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
 
 /**
  * Unsorted static helper-methods 
@@ -328,4 +336,108 @@
 		}
 		return true;
 	}
+	
+	/**
+	 * Workaround a CVS bug where a CVS Folder with no immediately contained files has an incorrect
+	 * Tag type stored in the TAG file.  In this case, the tag type is always BRANCH (Tv1)
+	 * 
+	 * The fix is for folders with no files, use the tag type for the containing project.  Since projects almost
+	 * always have files the TAG file is usually correct.
+	 * 
+	 * For the case where the folder tag name does not match the project tag name we can not do much so we just
+	 * return the folder tag which will currently always be a branch.
+	 * 
+	 * @param resource The IResource being tested.  Can not be null.
+	 * @param tag The CVSTag as reported by CVS for the IResource.  May be null.
+	 * @return CVSTag The corrected tag for the resource.  May be null.
+	 */
+	
+	public static CVSTag getAccurateFolderTag(IResource resource, CVSTag tag) {
+
+		// Determine if the folder contains files as immediate children.
+		if (resource.getType() != IResource.FOLDER) {
+			return tag;
+		}
+
+		IResource[] members = null;
+		try {
+			members = ((IFolder) resource).members();
+		} catch (CoreException e1) {
+			return tag;
+		}
+		
+		for (int i = 0; i < members.length; i++) {
+			if (members[i].getType() == IResource.FILE) {
+				return tag;
+			}
+		}
+	
+		// Folder contains no files so this may not really be a branch.
+		// Make the type the same as the project tag type if both are the same tag name.
+		IProject project = resource.getProject();
+		if (project == null) {
+			return tag;
+		}
+		
+		ICVSFolder projectFolder = CVSWorkspaceRoot.getCVSFolderFor(project);
+		FolderSyncInfo projectSyncInfo;
+		try {
+			projectSyncInfo = projectFolder.getFolderSyncInfo();
+		} catch (CVSException e) {
+			return tag;
+		}
+		
+		if (projectSyncInfo == null) {
+			return tag;
+		}
+		
+		CVSTag projectTag = projectSyncInfo.getTag();
+								
+		if (projectTag != null && projectTag.getName().equals(tag.getName())) {
+			return projectTag;
+		} else {
+			return tag;
+		}
+	}	
+	
+	/**
+	 * Workaround for CVS "bug" where CVS ENTRIES file does not contain correct
+	 * Branch vs. Version info.  Entries files always record a Tv1 so all entries would
+	 * appear as branches.
+	 * 	
+	 * By comparing the revision number to the tag name
+	 * you can determine if the tag is a branch or version.
+	 * 
+	 * @param cvsResource the resource to test.  Must nut be null.
+	 * @return the correct cVSTag.  May be null.
+	 */
+	
+	public static CVSTag getAccurateFileTag(ICVSResource cvsResource) throws CVSException {
+
+		CVSTag tag = null;
+		ResourceSyncInfo info = cvsResource.getSyncInfo();
+		if(info != null) {
+			tag = info.getTag();
+		}
+
+		FolderSyncInfo parentInfo = cvsResource.getParent().getFolderSyncInfo();
+		CVSTag parentTag = null;
+		if(parentInfo != null) {
+			parentTag = parentInfo.getTag();
+		}
+
+		if(tag != null) {
+			if(tag.getName().equals(info.getRevision())) {
+				tag = new CVSTag(tag.getName(), CVSTag.VERSION);
+			} else if(parentTag != null && tag.getName().equals(parentTag.getName())){
+				tag = new CVSTag(tag.getName(), parentTag.getType());
+			}
+		} else {
+			// if a file doesn't have tag info, very possible for example
+			// when the file is in HEAD, use the parents.
+			tag = parentTag;
+		}
+		
+		return tag;						
+	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ssh/plugin.xml b/bundles/org.eclipse.team.cvs.ssh/plugin.xml
index 7de275b..595c83c 100644
--- a/bundles/org.eclipse.team.cvs.ssh/plugin.xml
+++ b/bundles/org.eclipse.team.cvs.ssh/plugin.xml
@@ -2,7 +2,7 @@
 <plugin
 	name="%pluginName"
 	id="org.eclipse.team.cvs.ssh"
-	version="2.1.0"
+	version="2.1.1"
 	provider-name="%providerName"
 	class="org.eclipse.team.internal.ccvs.ssh.SSHPlugin">
 
diff --git a/bundles/org.eclipse.team.cvs.ssh/src/org/eclipse/team/internal/ccvs/ssh/Client.java b/bundles/org.eclipse.team.cvs.ssh/src/org/eclipse/team/internal/ccvs/ssh/Client.java
index 9b63f16..bb1d18d 100644
--- a/bundles/org.eclipse.team.cvs.ssh/src/org/eclipse/team/internal/ccvs/ssh/Client.java
+++ b/bundles/org.eclipse.team.cvs.ssh/src/org/eclipse/team/internal/ccvs/ssh/Client.java
@@ -365,6 +365,8 @@
 		if (socket == null) {
 			try {
 				socket = Util.createSocket(host, port, monitor);
+				// Bug 36351: disable buffering and send bytes immediately
+				socket.setTcpNoDelay(true);
 			} catch (InterruptedIOException e) {
 				// If we get this exception, chances are the host is not responding
 				throw new InterruptedIOException(Policy.bind("Client.socket", new Object[] {host}));//$NON-NLS-1$
diff --git a/bundles/org.eclipse.team.cvs.ui/plugin.xml b/bundles/org.eclipse.team.cvs.ui/plugin.xml
index 29cdffb..f9971301 100644
--- a/bundles/org.eclipse.team.cvs.ui/plugin.xml
+++ b/bundles/org.eclipse.team.cvs.ui/plugin.xml
@@ -2,7 +2,7 @@
 <plugin
 	id="org.eclipse.team.cvs.ui"
 	name="%pluginName"
-	version="2.1.0"
+	version="2.1.1"
 	provider-name="%providerName"
 	class="org.eclipse.team.internal.ccvs.ui.CVSUIPlugin">
 
@@ -100,7 +100,7 @@
 	<extension point="org.eclipse.ui.commands">
       <category
             name="%CVSActionSet.categoryName"
-            description="%CVSActionSet.category.description"
+            description="%CVSActionSet.description"
             id="org.eclipse.team.cvs.ui.actionSet">
       </category>
       <command
@@ -441,6 +441,7 @@
                label="%CheckoutAction.label"
                tooltip="%CheckoutAction.tooltip"
                class="org.eclipse.team.internal.ccvs.ui.actions.CheckoutAction"
+               menubarPath="checkoutGroup"
                helpContextId="org.eclipse.team.cvs.ui.checkout_module_action_context"
                id="org.eclipse.team.ccvs.ui.checkout">
          </action>       
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorConfiguration.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorConfiguration.java
index c48a25c..1017dfb 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorConfiguration.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorConfiguration.java
@@ -33,7 +33,6 @@
 	// bindings for resource states
 	public static final String DIRTY_FLAG = "dirty_flag"; //$NON-NLS-1$
 	public static final String ADDED_FLAG = "added_flag"; //$NON-NLS-1$
-	public static final String READ_ONLY_FLAG = "read_only_flag"; //$NON-NLS-1$
 	public static final String DEFAULT_DIRTY_FLAG = ">"; //$NON-NLS-1$
 	public static final String DEFAULT_ADDED_FLAG = "*"; //$NON-NLS-1$
 	
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java
index 6675bc7..0a9420a 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java
@@ -462,11 +462,10 @@
 		Map bindings = new HashMap();
 		bindings.put(CVSDecoratorConfiguration.RESOURCE_NAME, Policy.bind("name_of_the_resource_being_decorated_42")); //$NON-NLS-1$
 		bindings.put(CVSDecoratorConfiguration.RESOURCE_TAG, Policy.bind("the_tag_applied_to_the_resource_43")); //$NON-NLS-1$
-		bindings.put(CVSDecoratorConfiguration.FILE_KEYWORD, Policy.bind("keyword_subsitution_rule_for_the_resource_44")); //$NON-NLS-1$
+		bindings.put(CVSDecoratorConfiguration.FILE_KEYWORD, Policy.bind("keyword_substitution_rule_for_the_resource_44")); //$NON-NLS-1$
 		bindings.put(CVSDecoratorConfiguration.FILE_REVISION, Policy.bind("last_revision_loaded_into_workspace_45")); //$NON-NLS-1$
 		bindings.put(CVSDecoratorConfiguration.DIRTY_FLAG, Policy.bind("flag_indicating_that_the_file_has_outgoing_changes_46")); //$NON-NLS-1$
 		bindings.put(CVSDecoratorConfiguration.ADDED_FLAG, Policy.bind("flag_indicating_that_the_file_has_been_added_to_the_server_47")); //$NON-NLS-1$
-		bindings.put(CVSDecoratorConfiguration.READ_ONLY_FLAG, Policy.bind("flag_indicating_that_the_file_is_read_only")); //$NON-NLS-1$
 		return bindings;
 	}
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFilePropertiesPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFilePropertiesPage.java
index 181a821..0c6fd90 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFilePropertiesPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFilePropertiesPage.java
@@ -27,10 +27,10 @@
 import org.eclipse.team.internal.ccvs.core.ICVSFile;
 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
-import org.eclipse.ui.dialogs.PropertyPage;
+import org.eclipse.team.internal.ccvs.core.util.Util;
 import org.eclipse.ui.help.WorkbenchHelp;
 
-public class CVSFilePropertiesPage extends PropertyPage {
+public class CVSFilePropertiesPage extends CVSPropertiesPage {
 	IFile file;
 
 	/*
@@ -83,14 +83,8 @@
 			
 			// Tag
 			createLabel(composite, Policy.bind("CVSFilePropertiesPage.tag")); //$NON-NLS-1$
-			CVSTag tag = syncInfo.getTag();
-			if (tag == null) {
-				createLabel(composite, Policy.bind("CVSFilePropertiesPage.none")); //$NON-NLS-1$
-			} else {
-				// In an entry file we can't differentiate branch and version tags. They both appear
-				// as T<tagName>. Instead just display the tag name to the user.
-				createLabel(composite, tag.getName());
-			}
+			CVSTag tag = Util.getAccurateFileTag(cvsResource);
+			createLabel(composite, getTagLabel(tag));
 			
 			// Permissions
 			createLabel(composite, Policy.bind("CVSFilePropertiesPage.permissions")); //$NON-NLS-1$
@@ -105,7 +99,7 @@
 			createLabel(composite, Policy.bind("CVSFilePropertiesPage.error")); //$NON-NLS-1$
 			createLabel(composite, ""); //$NON-NLS-1$
 		}
-		WorkbenchHelp.setHelp(composite, IHelpContextIds.FILE_PROPERTY_PAGE);
+		WorkbenchHelp.setHelp(getControl(), IHelpContextIds.FILE_PROPERTY_PAGE);
 		return composite;
 	}
 	/**
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFolderPropertiesPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFolderPropertiesPage.java
index ab3d132..3f37314 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFolderPropertiesPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSFolderPropertiesPage.java
@@ -29,10 +29,10 @@
 import org.eclipse.team.internal.ccvs.core.ICVSFolder;
 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
-import org.eclipse.ui.dialogs.PropertyPage;
+import org.eclipse.team.internal.ccvs.core.util.Util;
 import org.eclipse.ui.help.WorkbenchHelp;
 
-public class CVSFolderPropertiesPage extends PropertyPage {
+public class CVSFolderPropertiesPage extends CVSPropertiesPage {
 
 	IFolder folder;
 	private Label root;
@@ -58,6 +58,10 @@
 				} else {
 					createLabel(composite, Policy.bind("CVSFolderPropertiesPage.notManaged"), 2); //$NON-NLS-1$
 				}
+			} else if (!cvsResource.isCVSFolder()) {
+				// We have a managed folder which is not a cvs folder. 
+				// This is really an invalid state but it does happen once in a while
+				createLabel(composite, Policy.bind("CVSFolderPropertiesPage.notCVSFolder"), 2); //$NON-NLS-1$
 			} else {
 				FolderSyncInfo syncInfo = cvsResource.getFolderSyncInfo();
 				createLabel(composite, Policy.bind("CVSFolderPropertiesPage.root")); //$NON-NLS-1$
@@ -68,24 +72,12 @@
 				// Tag
 				createLabel(composite, Policy.bind("CVSFilePropertiesPage.tag")); //$NON-NLS-1$
 				CVSTag tag = syncInfo.getTag();
-				if (tag == null) {
-					createLabel(composite, Policy.bind("CVSFilePropertiesPage.none")); //$NON-NLS-1$
-				} else {
-					switch (tag.getType()) {
-						case CVSTag.HEAD:
-							createLabel(composite, tag.getName());
-							break;
-						case CVSTag.VERSION:
-							createLabel(composite, Policy.bind("CVSFilePropertiesPage.version", tag.getName())); //$NON-NLS-1$
-							break;
-						case CVSTag.BRANCH:
-							createLabel(composite, Policy.bind("CVSFilePropertiesPage.branch", tag.getName())); //$NON-NLS-1$
-							break;
-						case CVSTag.DATE:
-							createLabel(composite, Policy.bind("CVSFilePropertiesPage.date", tag.getName())); //$NON-NLS-1$
-							break;
-					}
+
+				if (tag != null && tag.getType() == CVSTag.BRANCH) {
+					tag = Util.getAccurateFolderTag(folder, tag);				
 				}
+			
+				createLabel(composite, getTagLabel(tag));
 				
 				// Static-ness
 				if (syncInfo.getIsStatic()) {
@@ -118,7 +110,7 @@
 			// Display error text
 			createLabel(composite, Policy.bind("CVSFilePropertiesPage.error"), 2); //$NON-NLS-1$
 		}
-		WorkbenchHelp.setHelp(composite, IHelpContextIds.FOLDER_PROPERTY_PAGE);
+		WorkbenchHelp.setHelp(getControl(), IHelpContextIds.FOLDER_PROPERTY_PAGE);
 		return composite;
 	}
 
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 cb0f136..03fce33 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
@@ -23,6 +23,7 @@
 import org.eclipse.core.resources.IResourceVisitor;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.viewers.IDecoration;
@@ -34,6 +35,7 @@
 import org.eclipse.team.core.RepositoryProvider;
 import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
+import org.eclipse.team.internal.ccvs.core.CVSStatus;
 import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.core.CVSTeamProvider;
 import org.eclipse.team.internal.ccvs.core.ICVSFile;
@@ -53,6 +55,10 @@
 	extends LabelProvider
 	implements ILightweightLabelDecorator, IResourceStateChangeListener {
 
+	// remember exceptions that occur in the decorator for smart logging
+	// {plugin id -> list of status codes}
+	private static HashMap alreadyLoggedExceptions;
+	
 	// Images cached for better performance
 	private static ImageDescriptor dirty;
 	private static ImageDescriptor checkedIn;
@@ -92,6 +98,9 @@
 	public CVSLightweightDecorator() {
 		CVSProviderPlugin.addResourceStateChangeListener(this);
 		CVSProviderPlugin.broadcastDecoratorEnablementChanged(true /* enabled */);
+		
+		// we don't expect many exceptions hence the small initial value
+		alreadyLoggedExceptions = new HashMap(2);
 	}
 
 	public static boolean isDirty(final ICVSResource cvsResource) {
@@ -99,7 +108,7 @@
 			return !cvsResource.isIgnored() && cvsResource.isModified(null);
 		} catch (CVSException e) {
 			//if we get an error report it to the log but assume dirty
-			CVSUIPlugin.log(e.getStatus());
+			handleException(e);
 			return true;
 		}
 	}
@@ -176,6 +185,7 @@
 		} catch (CVSException e) {
 			// The was an exception in isIgnored. Don't decorate
 			//todo should log this error
+			handleException(e);
 			return;
 		}
 
@@ -265,7 +275,7 @@
 		CVSDecoratorConfiguration.decorate(decoration, format, bindings);
 			
 		} catch (CVSException e) {
-			CVSUIPlugin.log(e.getStatus());
+			handleException(e);
 			return;
 		}
 	}
@@ -343,7 +353,7 @@
 					}
 				}
 			} catch (CVSException e) {
-				CVSUIPlugin.log(e.getStatus());
+				handleException(e);
 				return null;
 			}
 		}
@@ -372,7 +382,7 @@
 					}
 				}
 			} catch (CVSException e) {
-				CVSUIPlugin.log(e.getStatus());
+				handleException(e);
 				return null;
 			}
 		}
@@ -382,7 +392,7 @@
 		try {
 			decorateEdited = provider.isWatchEditEnabled();
 		} catch (CVSException e1) {
-			CVSUIPlugin.log(e1);
+			handleException(e1);
 			decorateEdited = false;
 		}
 		
@@ -403,7 +413,7 @@
 					}
 				} catch (CVSException e) {
 					// log the exception and show the shared overlay
-					CVSUIPlugin.log(e);
+					handleException(e);
 				}
 			}
 			return checkedIn;
@@ -449,7 +459,7 @@
 			});
 			postLabelEvent(new LabelProviderChangedEvent(this, resources.toArray()));
 		} catch (CoreException e) {
-			CVSProviderPlugin.log(e.getStatus());
+			handleException(e);
 		}
 	}
 	
@@ -522,4 +532,46 @@
 		super.dispose();
 		CVSProviderPlugin.broadcastDecoratorEnablementChanged(false /* disabled */);
 	}
-}
+	
+	/**
+	 * Handle exceptions that occur in the decorator. 
+	 */
+	static private void handleException(Exception e) {
+		IStatus status = null;
+		if(e instanceof CoreException) {
+			status = ((CoreException)e).getStatus();
+		} else if(e instanceof CVSException) {
+			status = ((CVSException)e).getStatus();
+		}
+		if(status != null) {
+			logStatus(status);
+			IStatus[] children = status.getChildren();
+			for (int i = 0; i < children.length; i++) {
+				IStatus status2 = children[i];
+				logStatus(status2);
+			}
+		}
+	}
+	
+	/**
+	 * Log exceptions once for each {plugid,code} combination. This is to avoid
+	 * flooding the log. 
+	 * 
+	 * [Note: A better approach would be handle the specific out-of-sync with the file 
+	 * system case better and show an out-of-sync decorator.]  
+	 */
+	static private void logStatus(IStatus status) {
+		String pluginId = status.getPlugin();
+		List codes = (List)alreadyLoggedExceptions.get(pluginId);
+		Integer code = new Integer(status.getCode());
+		if(codes != null) {
+			if(codes.contains(code)) {
+				return;
+			}
+		} 
+		codes = new ArrayList(1);
+		codes.add(code);
+		alreadyLoggedExceptions.put(pluginId, codes);
+		CVSUIPlugin.log(new CVSStatus(status.getSeverity(), status.getCode(), Policy.bind("CVSDecorator.exceptionMessage", status.getMessage()))); //$NON-NLS-1$		
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSProjectPropertiesPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSProjectPropertiesPage.java
index 8da18ee..cef9cf7 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSProjectPropertiesPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSProjectPropertiesPage.java
@@ -51,12 +51,11 @@
 import org.eclipse.team.internal.ccvs.core.IUserInfo;
 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
-import org.eclipse.ui.dialogs.PropertyPage;
 import org.eclipse.ui.help.WorkbenchHelp;
 import org.eclipse.ui.model.WorkbenchContentProvider;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
 
-public class CVSProjectPropertiesPage extends PropertyPage {
+public class CVSProjectPropertiesPage extends CVSPropertiesPage {
 	IProject project;
 	ICVSRepositoryLocation oldLocation;
 	ICVSRepositoryLocation newLocation = null;
@@ -241,7 +240,7 @@
 		});
 		
 		initializeValues(oldLocation);
-		WorkbenchHelp.setHelp(composite, IHelpContextIds.PROJECT_PROPERTY_PAGE);
+		WorkbenchHelp.setHelp(getControl(), IHelpContextIds.PROJECT_PROPERTY_PAGE);
 		return composite;
 	}
 	/**
@@ -346,13 +345,9 @@
 		try {
 			ICVSFolder local = CVSWorkspaceRoot.getCVSFolderFor(project);
 			CVSTag tag = local.getFolderSyncInfo().getTag();
-			String tagName;
-			if (tag == null) {
-				tagName = CVSTag.DEFAULT.getName();
-			} else {
-				tagName = tag.getName();
-			}
-			tagLabel.setText(tagName);
+			
+			tagLabel.setText(getTagLabel(tag));
+
 		} catch (TeamException e) {
 			handle(e);
 		}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSPropertiesPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSPropertiesPage.java
new file mode 100644
index 0000000..c58aa8e
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSPropertiesPage.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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 org.eclipse.team.internal.ccvs.core.CVSTag;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+public abstract class CVSPropertiesPage extends PropertyPage {
+
+	/**
+	 * Return the appropriate Tag label for properties pages
+	 * based on the tag type.
+	 * @param tag
+	 * @return String
+	 */
+	
+	public static String getTagLabel(CVSTag tag) {
+	
+		if (tag == null) {
+			return Policy.bind("CVSFilePropertiesPage.none"); //$NON-NLS-1$
+		}
+		
+		switch (tag.getType()) {
+			case CVSTag.HEAD:
+				return tag.getName();
+			case CVSTag.VERSION:
+				return Policy.bind("CVSFilePropertiesPage.version", tag.getName()); //$NON-NLS-1$
+			case CVSTag.BRANCH:
+				return Policy.bind("CVSFilePropertiesPage.branch", tag.getName()); //$NON-NLS-1$
+			case CVSTag.DATE:
+				return Policy.bind("CVSFilePropertiesPage.date", tag.getName()); //$NON-NLS-1$
+			default :
+				return tag.getName();
+		}
+	}
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ExtMethodPreferencePage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ExtMethodPreferencePage.java
index b5c4de7..6aa2ab6 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ExtMethodPreferencePage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/ExtMethodPreferencePage.java
@@ -49,11 +49,12 @@
 		composite.setLayout(layout);
 		composite.setLayoutData(new GridData());
 		
-		Label intro = new Label(composite, SWT.LEFT);
+		Label intro = new Label(composite, SWT.LEFT | SWT.WRAP);
 		intro.setText(Policy.bind("ExtMethodPreferencePage_message")); //$NON-NLS-1$
 		GridData data = new GridData();
 		data.horizontalSpan = 3;
 		data.horizontalAlignment = GridData.FILL;
+		data.widthHint = 300;
 		intro.setLayoutData(data);
 		
 		new Label(composite, SWT.LEFT).setText(Policy.bind("ExtMethodPreferencePage_CVS_RSH")); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagConfigurationDialog.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagConfigurationDialog.java
index 45f2d4f..9fab279 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagConfigurationDialog.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/TagConfigurationDialog.java
@@ -96,12 +96,6 @@
 	// enable selecting auto-refresh files
 	private boolean allowSettingAutoRefreshFiles = true;
 	
-	// sizing default hints
-	private final int ALLOWREFRESH_WIDTH = 500;
-	private final int ALLOWREFRESH_HEIGHT = 625;
-	private final int NOREFRESH_WIDTH = 500;
-	private final int NOREFRESH_HEIGHT = 550;
-	
 	// preference keys
 	private final String ALLOWREFRESH_WIDTH_KEY = "AllowRefreshWidth"; //$NON-NLS-1$
 	private final String ALLOWREFRESH_HEIGHT_KEY = "AllowRefreshHeight"; //$NON-NLS-1$
@@ -160,8 +154,6 @@
 	 * @see Dialog#createDialogArea(Composite)
 	 */
 	protected Control createDialogArea(Composite parent) {
-//		setTitle(Policy.bind("TagConfigurationDialog.4")); //$NON-NLS-1$
-//		setTitleImage(null);
 		Composite shell = new Composite(parent, SWT.NONE);
 		GridData data = new GridData (GridData.FILL_BOTH);		
 		shell.setLayoutData(data);
@@ -746,16 +738,14 @@
 				height = settings.getInt(ALLOWREFRESH_HEIGHT_KEY);
 				width = settings.getInt(ALLOWREFRESH_WIDTH_KEY);
 			} catch(NumberFormatException e) {
-				height = ALLOWREFRESH_HEIGHT;
-				width = ALLOWREFRESH_WIDTH;
+				return super.getInitialSize();
 			}
 		} else {
 			try {
 				height = settings.getInt(NOREFRESH_HEIGHT_KEY);
 				width = settings.getInt(NOREFRESH_WIDTH_KEY);
 			} catch(NumberFormatException e) {
-				height = NOREFRESH_HEIGHT;
-				width = NOREFRESH_WIDTH;
+				return super.getInitialSize();
 			}
 		}
 		return new Point(width, height);
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkingSetSelectionArea.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkingSetSelectionArea.java
index 96eed39..170a659 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkingSetSelectionArea.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkingSetSelectionArea.java
@@ -129,11 +129,7 @@
 		data.horizontalIndent=15;
 		mruList.setLayoutData(data);
 		mruList.setFont(composite.getFont());
-		mruList.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleMruSelection();
-			}
-		});
+
 		selectButton = createButton(composite, Policy.bind("WorkingSetSelectionArea.workingSetOther"), GridData.HORIZONTAL_ALIGN_FILL); //$NON-NLS-1$
 		selectButton.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent event) {
@@ -143,6 +139,13 @@
 
 		initializeMru();
 		initializeWorkingSet();
+		
+		mruList.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleMruSelection();
+			}
+		});
+
 		return composite;
 	}
 
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareRemoteWithTagAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareRemoteWithTagAction.java
index a64185a..3eadde9 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareRemoteWithTagAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CompareRemoteWithTagAction.java
@@ -17,10 +17,15 @@
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 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.ICVSFile;
 import org.eclipse.team.internal.ccvs.core.ICVSFolder;
 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.connection.CVSRepositoryLocation;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTreeBuilder;
 import org.eclipse.team.internal.ccvs.ui.CVSCompareEditorInput;
 import org.eclipse.team.internal.ccvs.ui.ResourceEditionNode;
 import org.eclipse.team.internal.ccvs.ui.TagSelectionDialog;
@@ -39,22 +44,53 @@
 	 * @see org.eclipse.team.internal.ccvs.ui.actions.CVSAction#execute(org.eclipse.jface.action.IAction)
 	 */
 	protected void execute(IAction action) throws InvocationTargetException, InterruptedException {
+		
+		ICVSRemoteResource[] editions = getSelectedRemoteResources();
+		if (editions.length == 0) return;
+		final ICVSRemoteResource resource = editions[0];
+		
+		final ResourceEditionNode[] input = new ResourceEditionNode[] { null /* left */, null /* right */};
+		final CVSTag[] tag = new CVSTag[] { null};
+
 		run(new IRunnableWithProgress() {
 			public void run(IProgressMonitor monitor) throws InvocationTargetException {
-				ICVSRemoteResource[] editions = getSelectedRemoteResources();
-				if (editions.length == 0) return;
 				ICVSFolder folder;
-				if (editions[0] instanceof ICVSRemoteFolder) {
-					folder = (ICVSFolder)editions[0];
+				if (resource instanceof ICVSRemoteFolder) {
+					folder = (ICVSFolder)resource;
 				} else {
-					folder = editions[0].getParent();
+					folder = resource.getParent();
 				}
-				final CVSTag tag = TagSelectionDialog.getTagToCompareWith(getShell(), new ICVSFolder[] {folder});
-				if (tag == null) return;
-				ResourceEditionNode left = new ResourceEditionNode(editions[0]);
-				ResourceEditionNode right = new ResourceEditionNode(editions[0].forTag(tag));
+				tag[0] = TagSelectionDialog.getTagToCompareWith(getShell(), new ICVSFolder[] {folder});
+			}
+		}, false /* cancelable */, PROGRESS_BUSYCURSOR);
+		
+		if (tag[0] == null) return;
+		
+		final ICVSRemoteResource[] remote = new ICVSRemoteResource[] { null };
+		if (resource.isFolder()) {
+			remote[0] = resource.forTag(tag[0]);
+		} else {
+			run(new IRunnableWithProgress() {
+				public void run(IProgressMonitor monitor) throws InvocationTargetException {
+					try {
+						ICVSRepositoryLocation location = resource.getRepository();
+						remote[0] = RemoteFolderTreeBuilder.buildRemoteTree((CVSRepositoryLocation)location, (ICVSFile)resource, tag[0], monitor);
+					} catch (CVSException e) {
+						throw new InvocationTargetException(e);
+					}
+				}
+			}, false /* cancelable */, PROGRESS_DIALOG);
+		}
+		
+		input[0] = new ResourceEditionNode(resource);
+		input[1] = new ResourceEditionNode(remote[0]);
+		
+		if (input[0] == null || input[1] == null) return;
+		
+		run(new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) throws InvocationTargetException {
 				CompareUI.openCompareEditorOnPage(
-				  new CVSCompareEditorInput(left, right),
+				  new CVSCompareEditorInput(input[0] /* left */, input[1] /* right */),
 				  getTargetPage());
 			}
 		}, false /* cancelable */, PROGRESS_BUSYCURSOR);
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java
index e43f0ab..99180fb 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java
@@ -45,6 +45,7 @@
 import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.util.Util;
 import org.eclipse.team.internal.ccvs.ui.Policy;
 import org.eclipse.team.internal.ui.IPromptCondition;
 import org.eclipse.team.internal.ui.PromptingDialog;
@@ -453,31 +454,11 @@
 					if(info != null) {
 						tag = info.getTag();									
 					}
+					if (tag != null && tag.getType() == CVSTag.BRANCH) {
+						tag = Util.getAccurateFolderTag(resources[i], tag);
+					}
 				} else {
-					ResourceSyncInfo info = cvsResource.getSyncInfo();
-					if(info != null) {
-						tag = info.getTag();
-					}
-					// This magic is required because of a bug in CVS which doesn't store the
-					// type of tag for files correctly in the Entries file. They will always appear
-					// as branch tags "Tv1". By comparing the revision number to the tag name
-					// you can determine if the tag is a branch or version.
-					FolderSyncInfo parentInfo = cvsResource.getParent().getFolderSyncInfo();
-					CVSTag parentTag = null;
-					if(parentInfo != null) {
-						parentTag = parentInfo.getTag();
-					}
-					if(tag != null) {
-						if(tag.getName().equals(info.getRevision())) {
-							tag = new CVSTag(tag.getName(), CVSTag.VERSION);
-						} else if(parentTag != null){
-							tag = new CVSTag(tag.getName(), parentTag.getType());
-						}
-					} else {
-						// if a file doesn't have tag info, very possible for example
-						// when the file is in HEAD, use the parents.
-						tag = parentTag;
-					}
+					tag = Util.getAccurateFileTag(cvsResource);
 				}
 				if(tag == null) {
 					tag = new CVSTag();
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 be06282..554b4f1 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
@@ -126,6 +126,7 @@
 CVSDecorator.fileDecorationWithTag={0} [{1}:{2}] 
 CVSDecorator.fileDecorationNoTag={0} [{1}]
 CVSDecorator.folderDecoration={0} [{1}]
+CVSDecorator.exceptionMessage=Problems encountered in CVS decorator: {0}
 
 CVSDecoratorPreferencesPage.description=CVS Decorator settings:
 CVSDecoratorPreferencesPage.iconDescription=Choose which CVS resource states should be indicated using an icon decorator:
@@ -145,7 +146,7 @@
 CVSFilePropertiesPage.modified=Modified:
 CVSFilePropertiesPage.keywordMode=Keyword mode:
 CVSFilePropertiesPage.tag=Tag:
-CVSFilePropertiesPage.none=(none)
+CVSFilePropertiesPage.none=HEAD
 CVSFilePropertiesPage.version={0} (Version)
 CVSFilePropertiesPage.branch={0} (Branch)
 CVSFilePropertiesPage.date={0} (Date)
@@ -155,6 +156,7 @@
 
 CVSFolderPropertiesPage.ignored=The folder is ignored by CVS.
 CVSFolderPropertiesPage.notManaged=The folder is not managed by CVS.
+CVSFolderPropertiesPage.notCVSFolder=This folder has lost its CVS sharing information.
 CVSFolderPropertiesPage.root=Repository root:
 CVSFolderPropertiesPage.repository=Repository path:
 CVSFolderPropertiesPage.static=Static:
@@ -686,8 +688,8 @@
 Add_Varia&bles_17=Add Varia&bles...
 &Project_Format__18=&Project Format:
 Add_Variable&s_19=Add Variable&s...
-&Label_decoration_for_outgoing__20=&Label decoration for outgoing:
-Label_decorat&ion_for_added__22=Label decora&tion for added:
+&Label_decoration_for_outgoing__20=Di&rty flag:
+Label_decorat&ion_for_added__22=Added f&lag:
 Icon_Overlays_24=&Icons
 Sho&w_outgoing_25=Indicate is out&going
 Show_has_&remote_26=Indicate &has remote
@@ -709,9 +711,8 @@
 last_revision_loaded_into_workspace_45=last revision loaded into workspace
 flag_indicating_that_the_file_has_outgoing_changes_46=flag indicating that the file has outgoing changes
 flag_indicating_that_the_file_has_been_added_to_the_server_47=flag indicating that the file has been added to the server
-flag_indicating_that_the_file_is_read_only=flag indicating that the file is read-only
 
-ExtMethodPreferencePage_message=These variables define the external connection program to use with the \'ext\' connection method.\nThese values should be the same as the \'ext\' CVS command-line environment variable settings.
+ExtMethodPreferencePage_message=These variables define the external connection program to use with the \'ext\' connection method. These values should be the same as the \'ext\' CVS command-line environment variable settings.
 ExtMethodPreferencePage_CVS_RSH=CVS_&RSH:
 ExtMethodPreferencePage_Browse=&Browse...
 ExtMethodPreferencePage_Details=Select a program or script
@@ -883,7 +884,7 @@
 WatchEditPreferencePage.highjack=Edit the file &without informing the server
 
 Uneditaction.confirmMessage=Overwrite local changes to edited files?
-Uneditaction.confirmTitle=Comfirm Unedit
+Uneditaction.confirmTitle=Confirm Unedit
 
 FileModificationValidator.promptTitle=CVS Edit Files?
 FileModificationValidator.promptMessage=There are read-only files being modified. Should a 'cvs edit' be performed?
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 c4f8eed..b792631 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
@@ -176,7 +176,7 @@
 				connectionInfoChanged = true;
 			}
 		});
-		WorkbenchHelp.setHelp(composite, IHelpContextIds.REPOSITORY_LOCATION_PROPERTY_PAGE);
+		WorkbenchHelp.setHelp(getControl(), IHelpContextIds.REPOSITORY_LOCATION_PROPERTY_PAGE);
 		return composite;
 	}
 	/**
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 27aafc0..3da9241 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
@@ -276,8 +276,9 @@
 				ICVSRemoteFile file = root.getRemoteFile(filesToRefresh[i], CVSTag.DEFAULT);
 				tags.addAll(Arrays.asList(fetchTags(file, Policy.subMonitorFor(monitor, 5))));
 			}
-			clearTags(remotePath);
-			addTags(remotePath, (CVSTag[]) tags.toArray(new CVSTag[tags.size()]));
+			if (!tags.isEmpty()) {
+				addTags(remotePath, (CVSTag[]) tags.toArray(new CVSTag[tags.size()]));
+			}
 		} finally {
 			monitor.done();
 		}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositorySorter.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositorySorter.java
index 03cc26d..ad05080 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositorySorter.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/repo/RepositorySorter.java
@@ -16,9 +16,11 @@
 import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.core.ICVSRemoteFile;
 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.ui.model.BranchCategory;
 import org.eclipse.team.internal.ccvs.ui.model.CVSTagElement;
+import org.eclipse.team.internal.ccvs.ui.model.RemoteModule;
 import org.eclipse.team.internal.ccvs.ui.model.VersionCategory;
 
 public class RepositorySorter extends ViewerSorter {
@@ -29,6 +31,16 @@
 			}
 			return 1;
 		}
+		if (element instanceof RemoteModule) {
+			ICVSRemoteResource resource = ((RemoteModule)element).getCVSResource();
+			if (resource instanceof ICVSRemoteFolder) {
+				ICVSRemoteFolder folder = (ICVSRemoteFolder) resource;
+				if (folder.isDefinedModule()) {
+					return 7;
+				}
+			}
+			return 1;
+		}
 		if (element instanceof ICVSRemoteFile) {
 			return 2;
 		}
diff --git a/tests/org.eclipse.team.tests.cvs.core/plugin.xml b/tests/org.eclipse.team.tests.cvs.core/plugin.xml
index 494f000..16903d0 100644
--- a/tests/org.eclipse.team.tests.cvs.core/plugin.xml
+++ b/tests/org.eclipse.team.tests.cvs.core/plugin.xml
@@ -2,7 +2,7 @@
 <plugin
    id="org.eclipse.team.tests.cvs.core"
    name="Eclipse CVS Tests Core"
-   version="2.1.0"
+   version="2.1.1"
    provider-name="Eclipse.org">
 
    <runtime>
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/IsModifiedTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/IsModifiedTests.java
index f4152e4..f1eed90 100644
--- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/IsModifiedTests.java
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/IsModifiedTests.java
@@ -23,6 +23,7 @@
 import junit.framework.TestSuite;
 
 import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
@@ -523,7 +524,14 @@
 		assertModificationState(project, null, true);
 	}
 	
-	public void testExternalModifications() {
+	public void testExternalDeletion() throws CoreException, TeamException {
+		IProject project = createProject("testExternalDeletion", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/folder2/b.txt"});
+		IFile file = project.getFile("folder1/unmanaged.txt");
+		file.create(new ByteArrayInputStream("stuff".getBytes()), false, DEFAULT_MONITOR);
+		file.getLocation().toFile().delete();
+		file.refreshLocal(IResource.DEPTH_ZERO, DEFAULT_MONITOR);
+		assertTrue(!file.exists());
+		assertModificationState(project, null, true);
 	}
 
 }
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ResourceDeltaTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ResourceDeltaTest.java
index 407797b..7e0aede 100644
--- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ResourceDeltaTest.java
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/provider/ResourceDeltaTest.java
@@ -63,9 +63,13 @@
 	}
 
 	public static Test suite() {
-		TestSuite suite = new TestSuite(ResourceDeltaTest.class);
-		return new CVSTestSetup(suite);
-		//return new CVSTestSetup(new ResourceDeltaTest("testOrphanedSubtree"));
+		String testName = System.getProperty("eclipse.cvs.testName");
+		if (testName == null) {
+			TestSuite suite = new TestSuite(ResourceDeltaTest.class);
+			return new CVSTestSetup(suite);
+		} else {
+			return new CVSTestSetup(new ResourceDeltaTest(testName));
+		}
 	}
 	
 	public void assertNotManaged(ICVSFile cvsFile) throws CVSException {
@@ -275,4 +279,16 @@
 			}
 		}, 0);
 	}
+	
+	public void testExternalDeletion() throws CoreException, TeamException {
+		IProject project = createProject("testExternalDeletion", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/folder2/b.txt"});
+		IFile file = project.getFile("folder1/a.txt");
+		deepDelete(file.getLocation().toFile());
+		file.refreshLocal(IResource.DEPTH_ZERO, DEFAULT_MONITOR);
+		assertTrue(!file.exists());
+		ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(file);
+		assertTrue(cvsFile.isManaged());
+		byte[] syncBytes = cvsFile.getSyncBytes();
+		assertTrue(ResourceSyncInfo.isDeletion(syncBytes));
+	}
 }