Bug 81707 3.1M4 (compared to 3.1M3) cvs is EXTREMELY slow to commit
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizard.java
index 24abf09..26afef9 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizard.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizard.java
@@ -21,24 +21,21 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
+import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.core.IFileContentManager;
 import org.eclipse.team.core.Team;
+import org.eclipse.team.core.subscribers.Subscriber;
 import org.eclipse.team.core.synchronize.FastSyncInfoFilter;
 import org.eclipse.team.core.synchronize.SyncInfo;
 import org.eclipse.team.core.synchronize.SyncInfoSet;
 import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.internal.ccvs.core.CVSWorkspaceSubscriber;
 import org.eclipse.team.internal.ccvs.core.ICVSFolder;
 import org.eclipse.team.internal.ccvs.core.ICVSResource;
 import org.eclipse.team.internal.ccvs.core.client.Command;
@@ -49,16 +46,17 @@
 import org.eclipse.team.internal.ccvs.ui.operations.AddOperation;
 import org.eclipse.team.internal.ccvs.ui.operations.CVSOperation;
 import org.eclipse.team.internal.ccvs.ui.operations.CommitOperation;
+import org.eclipse.team.internal.core.subscribers.SubscriberSyncInfoCollector;
+import org.eclipse.team.ui.synchronize.ResourceScope;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.Workbench;
 
 /**
  * A wizard to commit the resources whose synchronization state is given in form
  * of a set of <code>SyncInfo</code>.
  */
-public class CommitWizard extends Wizard {
-    
-    private static final String COMMIT_WIZARD_SECTION = "CommitWizard"; //$NON-NLS-1$
+public class CommitWizard extends ResizableWizard {
     
     /**
      * An operation to add and commit resources to a CVS repository.
@@ -90,7 +88,6 @@
             fModesForNamesForOneTime= modes;
         }
         
-        
         public void setNewResources(IResource [] newResources) {
             this.fNewResources= newResources;
         }
@@ -116,104 +113,74 @@
         }
     }
     
+    private final IResource[] fResources;
     private final SyncInfoSet fOutOfSyncInfos;
     private final SyncInfoSet fUnaddedInfos;
+    private final CommitWizardParticipant fParticipant;
     
     private CommitWizardFileTypePage fFileTypePage;
     private CommitWizardCommitPage fCommitPage;
     
-    private IResource[] fResources;
-    WizardSizeSaver fSizeSaver;
-    
-
-    public CommitWizard(IResource [] resources) throws CVSException {
-        this(resources, getOutOfSyncInfos(resources));
-    }
-    
     public CommitWizard(SyncInfoSet infos) throws CVSException {
-        this(infos.getResources(), infos);
+        this(infos.getResources());
     }
     
-    private CommitWizard(IResource [] resources, SyncInfoSet syncInfos) throws CVSException {
-        super();
+    public CommitWizard(final IResource [] resources) throws CVSException {
+        
+        super("CommitWizard", CVSUIPlugin.getPlugin().getDialogSettings());
+        
         setWindowTitle(Policy.bind("CommitWizard.2")); //$NON-NLS-1$
         setDefaultPageImageDescriptor(CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_NEW_LOCATION));
         
-        setDialogSettings(CVSUIPlugin.getPlugin().getDialogSettings());
-
-        fSizeSaver= new WizardSizeSaver(this, COMMIT_WIZARD_SECTION);
-
         fResources= resources;
-        fOutOfSyncInfos= syncInfos;
-        fUnaddedInfos= getUnaddedInfos(syncInfos);
-
+        fParticipant= new CommitWizardParticipant(new ResourceScope(fResources), this);
+        
+        SyncInfoSet infos = getAllOutOfSync(resources);
+        fOutOfSyncInfos= new SyncInfoSet(infos.getNodes(new FastSyncInfoFilter.SyncInfoDirectionFilter(new int [] { SyncInfo.OUTGOING, SyncInfo.CONFLICTING })));
+        fUnaddedInfos= getUnaddedInfos(fOutOfSyncInfos);
     }
+
+	private SyncInfoSet getAllOutOfSync(final IResource[] resources) throws CVSException {
+		final SubscriberSyncInfoCollector syncInfoCollector = fParticipant.getSubscriberSyncInfoCollector();
+            try {
+				Workbench.getInstance().getProgressService().run(true, true, new IRunnableWithProgress() {
+				    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				    	monitor.beginTask("Collecting outgoing changes", IProgressMonitor.UNKNOWN);
+				    	syncInfoCollector.waitForCollector(monitor);
+				    	monitor.done();
+				    }
+				});
+			} catch (InvocationTargetException e) {
+				throw CVSException.wrapException(e);
+			} catch (InterruptedException e) {
+				throw new OperationCanceledException();
+			} 
+		return fParticipant.getSyncInfoSet();
+	}
     
     public boolean hasOutgoingChanges() {
         return fOutOfSyncInfos.size() > 0;
     }
     
-    private static SyncInfoSet getOutOfSyncInfos(IResource [] resources) {
-        final CVSWorkspaceSubscriber subscriber= CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber();
-        final SyncInfoSet infos= new SyncInfoSet();
-        subscriber.collectOutOfSync(resources, IResource.DEPTH_INFINITE, infos, new NullProgressMonitor());
-        
-        return new SyncInfoSet(infos.getNodes(new FastSyncInfoFilter.SyncInfoDirectionFilter(new int [] { SyncInfo.OUTGOING, SyncInfo.CONFLICTING })));
+    public CommitWizardFileTypePage getFileTypePage() {
+        return fFileTypePage;
     }
-    
-    private static SyncInfoSet getUnaddedInfos(SyncInfoSet infos) throws CVSException {
-        final SyncInfoSet unadded= new SyncInfoSet();        
-        for (final Iterator iter = infos.iterator(); iter.hasNext();) {
-            final SyncInfo info = (SyncInfo) iter.next();
-            final IResource file= info.getLocal();
-            if (!((file.getType() & IResource.FILE) == 0 || isAdded(file)))
-                unadded.add(info);
-        }
-        return unadded;
+
+    public CommitWizardCommitPage getCommitPage() {
+        return fCommitPage;
     }
-    
-    private static void getUnknownNamesAndExtension(SyncInfoSet infos, Collection names, Collection extensions) {
-        
-        final IFileContentManager manager= Team.getFileContentManager();
-        
-        for (final Iterator iter = infos.iterator(); iter.hasNext();) {
-            
-            final SyncInfo info = (SyncInfo)iter.next();
-            
-            final String extension= info.getLocal().getFileExtension();
-            if (extension != null && !manager.isKnownExtension(extension)) {
-                extensions.add(extension);
-            }
-            
-            final String name= info.getLocal().getName();
-            if (extension == null && name != null && !manager.isKnownFilename(name))
-                names.add(name);
-        }
+
+    public CommitWizardParticipant getParticipant() {
+        return fParticipant;
     }
-    
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.wizard.Wizard#addPages()
-     */
-    public void addPages() {
-        
-        final Collection names= new ArrayList();
-        final Collection extensions= new ArrayList();
-        getUnknownNamesAndExtension(fUnaddedInfos, names, extensions);
-        
-        if (names.size() + extensions.size() > 0) {
-            fFileTypePage= new CommitWizardFileTypePage(extensions, names); 
-            addPage(fFileTypePage);
-        }
-        
-        fCommitPage= new CommitWizardCommitPage(fResources, fFileTypePage);
-        addPage(fCommitPage);
-        
-        super.addPages();
+
+    public boolean canFinish() {
+        final IWizardPage current= getContainer().getCurrentPage();
+        if (current == fFileTypePage && fCommitPage != null)
+            return false;
+        return super.canFinish();
     }
-    
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.wizard.IWizard#performFinish()
-     */
+
     public boolean performFinish() {
         
         final String comment= getComment();
@@ -223,14 +190,14 @@
         final SyncInfoSet infos= fCommitPage.getInfosToCommit();
         if (infos.size() == 0)
             return true;
-
+        
         final SyncInfoSet unadded;
         try {
             unadded = getUnaddedInfos(infos);
         } catch (CVSException e1) {
             return false;
         }
-                    
+        
         final AddAndCommitOperation operation= new AddAndCommitOperation(getPart(), infos.getResources(), comment);
         
         if (fFileTypePage != null) {
@@ -243,7 +210,7 @@
             
             final Map namesToSave= new HashMap();
             final Map namesNotToSave= new HashMap();
-
+            
             fFileTypePage.getModesForNames(namesToSave, namesNotToSave);
             saveNameMappings(namesToSave);
             operation.setModesForNamesForOneTime(namesNotToSave);
@@ -260,9 +227,50 @@
         } catch (InterruptedException e) {
             return false;
         }
-        fSizeSaver.saveSize();
         
-        return true;
+        return super.performFinish();
+    }
+
+    public void addPages() {
+        
+        final Collection names= new ArrayList();
+        final Collection extensions= new ArrayList();
+        getUnknownNamesAndExtension(fUnaddedInfos, names, extensions);
+        
+        if (names.size() + extensions.size() > 0) {
+            fFileTypePage= new CommitWizardFileTypePage(extensions, names); 
+            addPage(fFileTypePage);
+        }
+        
+        fCommitPage= new CommitWizardCommitPage(fResources, this);
+        addPage(fCommitPage);
+        
+        super.addPages();
+    }
+
+    public void dispose() {
+        fParticipant.dispose();
+        super.dispose();
+    }
+
+    public static void run(Shell shell, IResource [] resources) throws CVSException {
+        try {
+			run(shell, new CommitWizard(resources));
+		} catch (OperationCanceledException e) {
+			// Ignore
+		}
+    }
+    
+    public static void run(Shell shell, SyncInfoSet infos) throws CVSException {
+        try {
+			run(shell, new CommitWizard(infos));
+		} catch (OperationCanceledException e) {
+			// Ignore
+		}
+    }
+
+    private IWorkbenchPart getPart() {
+        return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().getActivePart();
     }
     
     private String getComment() {
@@ -291,28 +299,44 @@
         return comment;
     }
     
-    public static void run(Shell shell, IResource [] resources) throws CVSException {
-        run(shell, new CommitWizard(resources));
-    }
-    
-    public static void run(Shell shell, SyncInfoSet infos) throws CVSException {
-        run(shell, new CommitWizard(infos));
-    }
-    
     private static void run(Shell shell, CommitWizard wizard) {
         if (!wizard.hasOutgoingChanges()) {
             MessageDialog.openInformation(shell, Policy.bind("CommitWizard.6"), Policy.bind("CommitWizard.7")); //$NON-NLS-1$ //$NON-NLS-2$
         } else {
-            final WizardDialog dialog= new WizardDialog(shell, wizard);
-            dialog.setMinimumPageSize(wizard.loadSize());
-            dialog.open();
+            open(shell, wizard);
         }
     }
 
+    private static void getUnknownNamesAndExtension(SyncInfoSet infos, Collection names, Collection extensions) {
+        
+        final IFileContentManager manager= Team.getFileContentManager();
+        
+        for (final Iterator iter = infos.iterator(); iter.hasNext();) {
+            
+            final SyncInfo info = (SyncInfo)iter.next();
+            
+            final String extension= info.getLocal().getFileExtension();
+            if (extension != null && !manager.isKnownExtension(extension)) {
+                extensions.add(extension);
+            }
+            
+            final String name= info.getLocal().getName();
+            if (extension == null && name != null && !manager.isKnownFilename(name))
+                names.add(name);
+        }
+    }
     
-    /**
-     * @param modesToPersist
-     */
+    private static SyncInfoSet getUnaddedInfos(SyncInfoSet infos) throws CVSException {
+        final SyncInfoSet unadded= new SyncInfoSet();        
+        for (final Iterator iter = infos.iterator(); iter.hasNext();) {
+            final SyncInfo info = (SyncInfo) iter.next();
+            final IResource file= info.getLocal();
+            if (!((file.getType() & IResource.FILE) == 0 || isAdded(file)))
+                unadded.add(info);
+        }
+        return unadded;
+    }
+    
     private static void saveExtensionMappings(Map modesToPersist) {
         
         final String [] extensions= new String [modesToPersist.size()];
@@ -341,14 +365,6 @@
         Team.getFileContentManager().addNameMappings(names, modes);
     }
     
-    /**
-     * Get the current workbench part.
-     * @return The workbench part.
-     */
-    private IWorkbenchPart getPart() {
-        return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().getActivePart();
-    }
-    
     private static boolean isAdded(IResource resource) throws CVSException {
         final ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
         if (cvsResource.isFolder()) {
@@ -356,19 +372,5 @@
         }
         return cvsResource.isManaged();
     }
-    
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.wizard.Wizard#canFinish()
-     */
-    public boolean canFinish() {
-        final IWizardPage current= getContainer().getCurrentPage();
-        if (current == fFileTypePage && fCommitPage != null)
-            return false;
-        return super.canFinish();
-    }
-    
-    public Point loadSize() {
-        return fSizeSaver.getSize();
-    }
 }    
 
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizardCommitPage.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizardCommitPage.java
index 2413be1..9d0c98a 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizardCommitPage.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizardCommitPage.java
@@ -11,21 +11,16 @@
 
 package org.eclipse.team.internal.ccvs.ui.wizards;
 
-import java.lang.reflect.InvocationTargetException;
-
 import org.eclipse.compare.structuremergeviewer.IDiffElement;
-import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
-import org.eclipse.jface.operation.IRunnableContext;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.jface.viewers.ILabelDecorator;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.wizard.IWizard;
@@ -35,34 +30,25 @@
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.*;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.team.core.subscribers.ChangeSet;
 import org.eclipse.team.core.synchronize.SyncInfo;
 import org.eclipse.team.core.synchronize.SyncInfoSet;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.ui.CVSDecoration;
 import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
 import org.eclipse.team.internal.ccvs.ui.CommitCommentArea;
 import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants;
 import org.eclipse.team.internal.ccvs.ui.Policy;
-import org.eclipse.team.internal.ccvs.ui.actions.IgnoreAction;
-import org.eclipse.team.internal.ccvs.ui.subscriber.CVSActionDelegateWrapper;
-import org.eclipse.team.internal.ccvs.ui.subscriber.CVSParticipantLabelDecorator;
-import org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceSynchronizeParticipant;
 import org.eclipse.team.internal.ui.PixelConverter;
 import org.eclipse.team.internal.ui.SWTUtils;
 import org.eclipse.team.internal.ui.Utils;
+import org.eclipse.team.internal.ui.synchronize.*;
 import org.eclipse.team.internal.ui.synchronize.SyncInfoModelElement;
 import org.eclipse.team.internal.ui.synchronize.SynchronizePageConfiguration;
-import org.eclipse.team.ui.synchronize.ChangeSetCapability;
 import org.eclipse.team.ui.synchronize.ISynchronizeModelElement;
 import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
-import org.eclipse.team.ui.synchronize.ISynchronizeScope;
 import org.eclipse.team.ui.synchronize.ParticipantPagePane;
-import org.eclipse.team.ui.synchronize.ResourceScope;
-import org.eclipse.team.ui.synchronize.SynchronizePageActionGroup;
 
 /**
  * This wizard page shows a preview of the commit operation and allows entering
@@ -70,28 +56,6 @@
  */
 public class CommitWizardCommitPage extends WizardPage implements IPropertyChangeListener {
     
-    /**
-     * The actions to be displayed in the context menu.
-     */
-    private class ActionContribution extends SynchronizePageActionGroup {
-        
-        public void initialize(ISynchronizePageConfiguration configuration) {
-            super.initialize(configuration);
-            appendToGroup(
-                    ISynchronizePageConfiguration.P_CONTEXT_MENU, 
-                    ISynchronizePageConfiguration.OBJECT_CONTRIBUTIONS_GROUP,
-                    new CVSActionDelegateWrapper(new IgnoreAction(), configuration));
-        }
-        
-        public void modelChanged(final ISynchronizeModelElement root) {
-            super.modelChanged(root);
-            Display.getDefault().asyncExec(new Runnable() {
-				public void run() {
-					updateForModelChange(root);
-				}
-			});
-        }
-    }
     
     /**
      * Saves the size of the wizard dialog.
@@ -131,92 +95,28 @@
         }
     }
     
-    /**
-     * An extension of the standard label decorator which configures the keyword substitution 
-     * mode according to the settings on the file type wizard page.
-     */
-    private class Decorator extends CVSParticipantLabelDecorator {
-        
-        public Decorator(ISynchronizePageConfiguration configuration) {
-            super(configuration);
-        }
-        
-        protected CVSDecoration getDecoration(IResource resource) throws CVSException {
-            final CVSDecoration decoration= super.getDecoration(resource);
-            if (fFileTypePage != null && resource instanceof IFile)
-                decoration.setKeywordSubstitution(fFileTypePage.getOption((IFile)resource).getShortDisplayText());
-            return decoration;
-        }
-    }
-    
-    /**
-     * A participant that uses our decorator instead of the standard one.
-     */
-    private class Participant extends WorkspaceSynchronizeParticipant {
-        public Participant(ISynchronizeScope scope) {
-            super(scope);
-        }
-        protected ILabelDecorator getLabelDecorator(ISynchronizePageConfiguration configuration) {
-            return new Decorator(configuration);
-        }
-        
-        public ChangeSetCapability getChangeSetCapability() {
-            return null; // we don't want that button
-        }
-        /* (non-Javadoc)
-		 * @see org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceSynchronizeParticipant#initializeConfiguration(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration)
-		 */
-		protected void initializeConfiguration( ISynchronizePageConfiguration configuration) {
-			super.initializeConfiguration(configuration);
-	        configuration.setProperty(ISynchronizePageConfiguration.P_TOOLBAR_MENU, new String[] {ISynchronizePageConfiguration.LAYOUT_GROUP});
-	        configuration.setProperty(ISynchronizePageConfiguration.P_CONTEXT_MENU, ISynchronizePageConfiguration.DEFAULT_CONTEXT_MENU);
-	        configuration.addActionContribution(new ActionContribution());
-	        
-	        // Wrap the container so that we can update the enablements after the runnable
-	        // (i.e. the container resets the state to what it was at the beginning of the
-	        // run even if the state of the page changed. Remove from View changes the state)
-	        configuration.setRunnableContext(new IRunnableContext() {
-				public void run(boolean fork, boolean cancelable,
-						IRunnableWithProgress runnable)
-						throws InvocationTargetException, InterruptedException {
-					getContainer().run(fork, cancelable, runnable);
-					updateEnablements();
-				}
-			});
-	        configuration.setSupportedModes(ISynchronizePageConfiguration.OUTGOING_MODE);
-	        configuration.setMode(ISynchronizePageConfiguration.OUTGOING_MODE);
-		}
-		/* (non-Javadoc)
-		 * @see org.eclipse.team.ui.synchronize.AbstractSynchronizeParticipant#doesSupportSynchronize()
-		 */
-		public boolean doesSupportSynchronize() {
-			return false;
-		}
-    }
-    
     private final CommitCommentArea fCommentArea;
-    private final IResource [] fResources;
-    
     private final SettingsSaver fSettingsSaver;
     
     private ISynchronizePageConfiguration fConfiguration;
     private SashForm fSashForm;
-    protected final CommitWizardFileTypePage fFileTypePage;
-	private ParticipantPagePane fPagePane;
-	private Participant fParticipant;
     
-    public CommitWizardCommitPage(IResource [] resources, CommitWizardFileTypePage fileTypePage) {
+    protected final CommitWizard fWizard;
+    
+	private ParticipantPagePane fPagePane;
+    
+    public CommitWizardCommitPage(IResource [] resources, CommitWizard wizard) {
+        
         super(Policy.bind("CommitWizardCommitPage.0")); //$NON-NLS-1$
         setTitle(Policy.bind("CommitWizardCommitPage.0")); //$NON-NLS-1$
         setDescription(Policy.bind("CommitWizardCommitPage.2")); //$NON-NLS-1$
         
         fSettingsSaver= new SettingsSaver();
-        fFileTypePage= fileTypePage;
+        fWizard= wizard;
         fCommentArea= new CommitCommentArea();
         fCommentArea.setProposedComment(getProposedComment(resources));
         if (resources.length > 0)
             fCommentArea.setProject(resources[0].getProject());
-        fResources= resources;
     }
     
     /* (non-Javadoc)
@@ -266,14 +166,14 @@
         
         createPlaceholder(composite);
         
-        fParticipant = new Participant(new ResourceScope(fResources));
-        fConfiguration= fParticipant.createPageConfiguration();
-        fPagePane= new ParticipantPagePane(getShell(), true /* modal */, fConfiguration, fParticipant);
+        final CommitWizardParticipant participant= fWizard.getParticipant();
+        fConfiguration= participant.createPageConfiguration();
+        fPagePane= new ParticipantPagePane(getShell(), true /* modal */, fConfiguration, participant);
         Control control = fPagePane.createPartControl(composite);
         control.setLayoutData(SWTUtils.createHVFillGridData());
     }
-    
-    /* (non-Javadoc)
+
+	/* (non-Javadoc)
 	 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
 	 */
 	public void dispose() {
@@ -281,8 +181,6 @@
 		// Disposing of the page pane will dispose of the page and the configuration
 		if (fPagePane != null)
 			fPagePane.dispose();
-		if (fParticipant != null)
-			fParticipant.dispose();
 	}
 	
     private void createPlaceholder(final Composite composite) {
@@ -305,27 +203,31 @@
      */
     public void setVisible(boolean visible) {
         super.setVisible(visible);
-        fCommentArea.setFocus();
-        fConfiguration.getPage().getViewer().refresh();
         expand();
+        fCommentArea.setFocus();
     }
     
     protected void expand() {
         final Viewer viewer= fConfiguration.getPage().getViewer();
         if (viewer instanceof TreeViewer) {
-            ((TreeViewer)viewer).expandAll();
+        	try {
+	        	viewer.getControl().setRedraw(false);
+	            ((TreeViewer)viewer).expandAll();
+        	} finally {
+        		viewer.getControl().setRedraw(true);
+        	}
         }
     }
     
 	/*
 	 * Expand the sync elements and update the page enablement
 	 */
-	protected void updateForModelChange(ISynchronizeModelElement root) {
+	protected void updateForModelChange() {
 		expand();
 		updateEnablements();
 	}
 	
-	private void updateEnablements() {
+	public void updateEnablements() {
 		SyncInfoSet set = fConfiguration.getSyncInfoSet();
 		if (set.hasConflicts()) {
 			setErrorMessage(Policy.bind("CommitWizardCommitPage.4")); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizardParticipant.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizardParticipant.java
new file mode 100644
index 0000000..a2ed529
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/CommitWizardParticipant.java
@@ -0,0 +1,121 @@
+package org.eclipse.team.internal.ccvs.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.ui.CVSDecoration;
+import org.eclipse.team.internal.ccvs.ui.actions.IgnoreAction;
+import org.eclipse.team.internal.ccvs.ui.subscriber.CVSActionDelegateWrapper;
+import org.eclipse.team.internal.ccvs.ui.subscriber.CVSParticipantLabelDecorator;
+import org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceSynchronizeParticipant;
+import org.eclipse.team.ui.synchronize.ChangeSetCapability;
+import org.eclipse.team.ui.synchronize.ISynchronizeModelElement;
+import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
+import org.eclipse.team.ui.synchronize.ISynchronizeScope;
+import org.eclipse.team.ui.synchronize.SynchronizePageActionGroup;
+
+/**
+ * A participant that uses our decorator instead of the standard one.
+ */
+public class CommitWizardParticipant extends WorkspaceSynchronizeParticipant {
+    
+    /**
+     * The actions to be displayed in the context menu.
+     */
+    private class ActionContribution extends SynchronizePageActionGroup {
+        
+        public void initialize(ISynchronizePageConfiguration configuration) {
+            super.initialize(configuration);
+            appendToGroup(
+                    ISynchronizePageConfiguration.P_CONTEXT_MENU, 
+                    ISynchronizePageConfiguration.OBJECT_CONTRIBUTIONS_GROUP,
+                    new CVSActionDelegateWrapper(new IgnoreAction(), configuration));
+        }
+        
+        public void modelChanged(final ISynchronizeModelElement root) {
+            super.modelChanged(root);
+            Display.getDefault().asyncExec(new Runnable() {
+                public void run() {                
+                    final CommitWizardCommitPage page= fWizard.getCommitPage();
+                    if (page != null)
+                        page.updateForModelChange();
+                }
+            });
+        }
+    }
+
+    /**
+     * An extension of the standard label decorator which configures the keyword substitution 
+     * mode according to the settings on the file type wizard page.
+     */
+    private static class Decorator extends CVSParticipantLabelDecorator {
+        
+        private final CommitWizard fWizard;
+
+        public Decorator(ISynchronizePageConfiguration configuration, CommitWizard wizard) {
+            super(configuration);
+            fWizard= wizard;
+        }
+        
+        protected CVSDecoration getDecoration(IResource resource) throws CVSException {
+            final CVSDecoration decoration= super.getDecoration(resource);
+            final CommitWizardFileTypePage page= fWizard.getFileTypePage();
+            
+            if (page != null && resource instanceof IFile) 
+                decoration.setKeywordSubstitution(page.getOption((IFile)resource).getShortDisplayText());
+            return decoration;
+        }
+    }
+    
+    final CommitWizard fWizard;
+    
+    public CommitWizardParticipant(ISynchronizeScope scope, CommitWizard wizard) {
+        super(scope);
+        fWizard= wizard;
+    }
+    
+    protected ILabelDecorator getLabelDecorator(ISynchronizePageConfiguration configuration) {
+        return new Decorator(configuration, fWizard);
+    }
+    
+    public ChangeSetCapability getChangeSetCapability() {
+        return null; // we don't want that button
+    }
+    /* (non-Javadoc)
+     * @see org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceSynchronizeParticipant#initializeConfiguration(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration)
+     */
+    protected void initializeConfiguration( ISynchronizePageConfiguration configuration) {
+        super.initializeConfiguration(configuration);
+        configuration.setProperty(ISynchronizePageConfiguration.P_TOOLBAR_MENU, new String[] {ISynchronizePageConfiguration.LAYOUT_GROUP});
+        configuration.setProperty(ISynchronizePageConfiguration.P_CONTEXT_MENU, ISynchronizePageConfiguration.DEFAULT_CONTEXT_MENU);
+        configuration.addActionContribution(new ActionContribution());
+        
+        // Wrap the container so that we can update the enablements after the runnable
+        // (i.e. the container resets the state to what it was at the beginning of the
+        // run even if the state of the page changed. Remove from View changes the state)
+        configuration.setRunnableContext(new IRunnableContext() {
+            public void run(boolean fork, boolean cancelable,
+                    IRunnableWithProgress runnable)
+                    throws InvocationTargetException, InterruptedException {
+                fWizard.getContainer().run(fork, cancelable, runnable);
+                final CommitWizardCommitPage page= fWizard.getCommitPage();
+                if (page != null)
+                    page.updateEnablements();
+            }
+        });
+        configuration.setSupportedModes(ISynchronizePageConfiguration.OUTGOING_MODE);
+        configuration.setMode(ISynchronizePageConfiguration.OUTGOING_MODE);
+    }
+    /* (non-Javadoc)
+     * @see org.eclipse.team.ui.synchronize.AbstractSynchronizeParticipant#doesSupportSynchronize()
+     */
+    public boolean doesSupportSynchronize() {
+        return false;
+    }
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ModeWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ModeWizard.java
index 0517954..367a926 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ModeWizard.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ModeWizard.java
@@ -19,9 +19,6 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IResourceVisitor;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.team.core.TeamException;
 import org.eclipse.team.internal.ccvs.core.ICVSFile;
@@ -41,10 +38,7 @@
  *     an option to include them in the operation anyways.
  * 5.  Perform the operation on Finish.
  */
-public class ModeWizard extends Wizard {
-    
-    private static final int DEFAULT_WIDTH= 500;
-    private static final int DEFAULT_HEIGHT= 400;
+public class ModeWizard extends ResizableWizard {
     
     public interface ModeChange extends Comparable {
         
@@ -99,24 +93,14 @@
         }
     }
 
-
     private List fChanges;
-    private static final String MODE_WIZARD_SECTION = "ModeWizard"; //$NON-NLS-1$
-    private final WizardSizeSaver fSizeSaver;
 
-	
     public static ModeWizard run(Shell shell, IResource [] resources) {
         final ModeWizard wizard= new ModeWizard(resources);
-        final WizardDialog dialog= new WizardDialog(shell, wizard);
-        dialog.setMinimumPageSize(wizard.loadSize());
-        dialog.open();
+        open(shell, wizard);
         return wizard;
     }
 
-	private Point loadSize() {
-        return fSizeSaver.getSize();
-    }
-
     /**
 	 * Creates a wizard to set the keyword substitution mode for the specified resources.
 	 * 
@@ -125,11 +109,8 @@
 	 * @param defaultOption the keyword substitution option to select by default
 	 */
 	protected ModeWizard(IResource[] resources) {
-		super();
+		super("ModeWizard", CVSUIPlugin.getPlugin().getDialogSettings(), 500, 400);
 		setWindowTitle("Change the CVS file transfer mode");
-        setDialogSettings(CVSUIPlugin.getPlugin().getDialogSettings());
-
-        fSizeSaver= new WizardSizeSaver(this, MODE_WIZARD_SECTION, DEFAULT_WIDTH, DEFAULT_HEIGHT);
         fChanges= getModeChanges(resources);
 	}
 
@@ -144,14 +125,6 @@
 		return true;
 	}
 
-	/* (Non-javadoc)
-	 * Method declared on IWizard.
-	 */
-	public boolean performFinish() {
-        fSizeSaver.saveSize();
-        return true;
-    }
-    
     private List getModeChanges(IResource [] resources) {
         
         final ArrayList changes= new ArrayList();
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ResizableWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ResizableWizard.java
new file mode 100644
index 0000000..7798344
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/ResizableWizard.java
@@ -0,0 +1,78 @@
+package org.eclipse.team.internal.ccvs.ui.wizards;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Persists the size of the wizard dialog.
+ */
+public class ResizableWizard extends Wizard {
+	
+	private final int DEFAULT_WIDTH;
+	private final int DEFAULT_HEIGHT;
+    
+    private static final String BOUNDS_HEIGHT_KEY = "width"; //$NON-NLS-1$
+    private static final String BOUNDS_WIDTH_KEY = "height"; //$NON-NLS-1$
+    
+    final String fSectionName;
+    
+    public ResizableWizard(String sectionName, IDialogSettings settings) {
+    	this(sectionName, settings, 300, 400);
+    }
+    
+    protected ResizableWizard(String sectionName, IDialogSettings settings, int defaultWidth, int defaultHeight) {
+        DEFAULT_WIDTH= defaultWidth;
+        DEFAULT_HEIGHT= defaultHeight;
+        fSectionName= sectionName;
+        setDialogSettings(settings);
+    }
+    
+    protected static int open(Shell shell, ResizableWizard wizard) {
+        final WizardDialog dialog= new WizardDialog(shell, wizard);
+        dialog.setMinimumPageSize(wizard.loadSize());
+        return dialog.open();
+    }
+    
+    public void saveSize() {
+        final Rectangle bounds= getContainer().getCurrentPage().getControl().getParent().getClientArea();
+    	final IDialogSettings settings= getDialogSettings();
+    	if (settings == null)
+    		return;
+    	
+    	IDialogSettings section= settings.getSection(fSectionName); 
+    	if (section == null)
+    		section= settings.addNewSection(fSectionName);
+    	
+        section.put(BOUNDS_WIDTH_KEY, bounds.width);
+        section.put(BOUNDS_HEIGHT_KEY, bounds.height);
+    }
+    
+    public Point loadSize() {
+        final Point size= new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+        
+    	final IDialogSettings settings= getDialogSettings();
+    	if (settings == null)
+    		return size;
+    	
+    	final IDialogSettings section= settings.getSection(fSectionName);
+    	if (section == null)
+    		return size;
+
+        try {
+            size.x= section.getInt(BOUNDS_WIDTH_KEY);
+            size.y= section.getInt(BOUNDS_HEIGHT_KEY);
+        } catch (NumberFormatException e) {
+        }
+        return size;
+    }
+
+
+    public boolean performFinish() {
+        saveSize();
+        return true;
+    }
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/UpdateWizard.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/UpdateWizard.java
index 69c0849..cea0616 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/UpdateWizard.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/UpdateWizard.java
@@ -19,9 +19,6 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.jface.wizard.WizardDialog;
-import org.eclipse.swt.graphics.Point;
 import org.eclipse.team.internal.ccvs.core.CVSException;
 import org.eclipse.team.internal.ccvs.core.CVSTag;
 import org.eclipse.team.internal.ccvs.core.ICVSFolder;
@@ -37,28 +34,22 @@
 import org.eclipse.team.internal.ccvs.ui.tags.TagSourceWorkbenchAdapter;
 import org.eclipse.ui.IWorkbenchPart;
 
-public class UpdateWizard extends Wizard {
+public class UpdateWizard extends ResizableWizard {
 	
-	private static final String UPDATE_WIZARD_SECTION = "UpdateWizard"; //$NON-NLS-1$
-
 	private IResource[] resources;
 	private final IWorkbenchPart part;
-	private final WizardSizeSaver fSizeSaver;
 	private TagSelectionWizardPage tagSelectionPage;
 	
 	protected UpdateWizard(IWorkbenchPart part, IResource[] resources) {
+        super("UpdateWizard", CVSUIPlugin.getPlugin().getDialogSettings());
 		this.part = part;
 		this.resources = resources;
-		fSizeSaver= new WizardSizeSaver(this, UPDATE_WIZARD_SECTION);
-		setDialogSettings(CVSUIPlugin.getPlugin().getDialogSettings());
 		setWindowTitle(Policy.bind("UpdateWizard.title")); //$NON-NLS-1$
 	}
 	
     public static void run(IWorkbenchPart part, IResource [] resources) {
-        UpdateWizard wizard = new UpdateWizard(part, resources);
-		final WizardDialog dialog= new WizardDialog(part.getSite().getShell(), wizard);
-		dialog.setMinimumPageSize(wizard.loadSize());
-		dialog.open();
+        final UpdateWizard wizard = new UpdateWizard(part, resources);
+        open(part.getSite().getShell(), wizard);
     }
     
 	public void addPages() {
@@ -106,11 +97,6 @@
 			return false;
 		}
 
-		fSizeSaver.saveSize();
-		return true;
+		return super.performFinish();
 	}
-	
-    public Point loadSize() {
-        return fSizeSaver.getSize();
-    }
 }
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/WizardSizeSaver.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/WizardSizeSaver.java
deleted file mode 100644
index 7b6a7e7..0000000
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/wizards/WizardSizeSaver.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.eclipse.team.internal.ccvs.ui.wizards;
-
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.wizard.IWizard;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-
-/**
- * Persists the size of the wizard dialog.
- */
-public class WizardSizeSaver {
-	
-	private final int DEFAULT_WIDTH;
-	private final int DEFAULT_HEIGHT;
-    
-    private static final String BOUNDS_HEIGHT_KEY = "width"; //$NON-NLS-1$
-    private static final String BOUNDS_WIDTH_KEY = "height"; //$NON-NLS-1$
-    
-    final IWizard fWizard;
-    final String fSectionName;
-    
-    public WizardSizeSaver(IWizard wizard, String sectionName) {
-    	this(wizard, sectionName, 300, 400);
-    }
-    
-    public WizardSizeSaver(IWizard wizard, String sectionName, int defaultWidth, int defaultHeight) {
-        DEFAULT_WIDTH= defaultWidth;
-        DEFAULT_HEIGHT= defaultHeight;
-        fWizard= wizard;
-        fSectionName= sectionName;
-    }
-    
-    public void saveSize() {
-        
-        final Rectangle bounds= fWizard.getContainer().getCurrentPage().getControl().getParent().getClientArea();
-    	final IDialogSettings settings= fWizard.getDialogSettings();
-    	if (settings == null)
-    		return;
-    	
-    	IDialogSettings section= settings.getSection(fSectionName); 
-    	if (section == null)
-    		section= settings.addNewSection(fSectionName);
-    	
-        section.put(BOUNDS_WIDTH_KEY, bounds.width);
-        section.put(BOUNDS_HEIGHT_KEY, bounds.height);
-    }
-    
-    public Point getSize() {
-        final Point size= new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
-        
-    	final IDialogSettings settings= fWizard.getDialogSettings();
-    	if (settings == null)
-    		return size;
-    	
-    	final IDialogSettings section= settings.getSection(fSectionName);
-    	if (section == null)
-    		return size;
-
-        try {
-            size.x= section.getInt(BOUNDS_WIDTH_KEY);
-            size.y= section.getInt(BOUNDS_HEIGHT_KEY);
-        } catch (NumberFormatException e) {
-        }
-        return size;
-    }
-}