This commit was manufactured by cvs2svn to create branch
'branch_CVSQuickDiffProvider'.

Cherrypick from master 2003-09-17 18:37:36 UTC Michael Valenta <mvalenta> 'Fixed bug in fetch of memebers':
    bundles/org.eclipse.team.cvs.ui/icons/full/clcl16/synced.gif
    bundles/org.eclipse.team.cvs.ui/icons/full/elcl16/synced.gif
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RepositoryLocationSchedulingRule.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java
    bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java
diff --git a/bundles/org.eclipse.team.cvs.ui/icons/full/clcl16/synced.gif b/bundles/org.eclipse.team.cvs.ui/icons/full/clcl16/synced.gif
new file mode 100644
index 0000000..f865f3a
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/icons/full/clcl16/synced.gif
Binary files differ
diff --git a/bundles/org.eclipse.team.cvs.ui/icons/full/elcl16/synced.gif b/bundles/org.eclipse.team.cvs.ui/icons/full/elcl16/synced.gif
new file mode 100644
index 0000000..ae5d548
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/icons/full/elcl16/synced.gif
Binary files differ
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RepositoryLocationSchedulingRule.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RepositoryLocationSchedulingRule.java
new file mode 100644
index 0000000..9422811
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/model/RepositoryLocationSchedulingRule.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui.model;
+
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
+
+/**
+ * A simple job scheduling rule for serializing jobs for an ICVSRepositoryLocation
+ */
+public class RepositoryLocationSchedulingRule implements ISchedulingRule {
+	ICVSRepositoryLocation location;
+	public RepositoryLocationSchedulingRule(ICVSRepositoryLocation location) {
+		this.location = location;
+	}		
+	public boolean isConflicting(ISchedulingRule rule) {
+		if(rule instanceof RepositoryLocationSchedulingRule) {
+			return ((RepositoryLocationSchedulingRule)rule).location.equals(location);
+		}
+		return false;
+	}
+	public boolean contains(ISchedulingRule rule) {		
+		return isConflicting(rule);
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java
new file mode 100644
index 0000000..6b2fb38
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSBlockingRunnableContext.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui.operations;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.team.internal.ccvs.ui.Policy;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * This CVS runnable context blocks the UI and can therfore have a shell assigned to
+ * it (since the shell won't be closed by the user before the runnable completes.
+ */
+public class CVSBlockingRunnableContext implements ICVSRunnableContext {
+
+	private Shell shell;
+	private IRunnableContext runnableContext;
+	
+	public CVSBlockingRunnableContext(Shell shell) {
+		this.shell = shell;
+	}
+
+	/**
+	 * Run the given runnable in the context of the receiver. By default, the
+	 * progress is provided by the active workbench windows but subclasses may
+	 * override this to provide progress in some other way (Progress Monitor or
+	 * job).
+	 */
+	public void run(String title, ISchedulingRule schedulingRule, boolean postponeBuild, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
+		getRunnableContext().run(true /* fork */, true /* cancelable */, wrapRunnable(title, schedulingRule, postponeBuild, runnable));
+	}
+
+	protected IRunnableContext getRunnableContext() {
+		if (runnableContext == null) {
+			return PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+		}
+		return runnableContext;
+	}
+
+	/*
+	 * Return an IRunnableWithProgress that sets the task name for the progress monitor
+	 * and runs in a workspace modify operation if requested.
+	 */
+	private IRunnableWithProgress wrapRunnable(final String title, final ISchedulingRule schedulingRule, final boolean postponeBuild, final IRunnableWithProgress runnable) {
+		return new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				monitor.beginTask(title, 100);
+				try {
+					if (schedulingRule == null && !postponeBuild) {
+						runnable.run(Policy.subMonitorFor(monitor, 100));
+					} else {
+						final Exception[] exception = new Exception[] { null };
+						ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
+							public void run(IProgressMonitor pm) throws CoreException {
+								try {
+									runnable.run(pm);
+								} catch (InvocationTargetException e) {
+									exception[0] = e;
+								} catch (InterruptedException e) {
+									exception[0] = e;
+								}
+							}
+						}, schedulingRule, Policy.subMonitorFor(monitor, 100));
+						if (exception[0] != null) {
+							if (exception[0] instanceof InvocationTargetException) {
+								throw (InvocationTargetException)exception[0];
+							} else if (exception[0] instanceof InterruptedException) {
+								throw (InterruptedException)exception[0];	
+							}
+						}
+					}
+				} catch (CoreException e) {
+					throw new InvocationTargetException(e);
+				} finally {
+					monitor.done();
+				}
+			}
+		};
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSRunnableContext#getShell()
+	 */
+	public Shell getShell() {
+		return shell;
+	}
+
+	/**
+	 * Set the shell to be used by the owner of this context to prompt the user.
+	 * @param shell
+	 */
+	public void setShell(Shell shell) {
+		this.shell = shell;
+	}
+
+	/**
+	 * @param runnableContext
+	 */
+	public void setRunnableContext(IRunnableContext runnableContext) {
+		this.runnableContext = runnableContext;
+	}
+
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java
new file mode 100644
index 0000000..dc8ee0e
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSNonblockingRunnableContext.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui.operations;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * This runnable context executes it's operation in the context of a background job.
+ */
+public class CVSNonblockingRunnableContext implements ICVSRunnableContext {
+
+	private IJobChangeListener listener;
+
+	public CVSNonblockingRunnableContext() {
+		this(null);
+	}
+	
+	public CVSNonblockingRunnableContext(IJobChangeListener listener) {
+		this.listener = listener;
+	}
+
+	protected IStatus run(IRunnableWithProgress runnable, IProgressMonitor monitor) {
+		try {
+			runnable.run(monitor);
+		} catch (InvocationTargetException e) {
+			return CVSException.wrapException(e).getStatus();
+		} catch (InterruptedException e) {
+			return Status.OK_STATUS;
+		}
+		return Status.OK_STATUS;
+	}
+	
+	protected Job getBasicJob(String title, final IRunnableWithProgress runnable) {
+		return new Job(title) {
+			public IStatus run(IProgressMonitor monitor) {
+				return CVSNonblockingRunnableContext.this.run(runnable, monitor);
+			}
+		};
+	}
+	
+	protected Job getWorkspaceJob(String title, final IRunnableWithProgress runnable) {
+		return new WorkspaceJob(title) {
+			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+				return CVSNonblockingRunnableContext.this.run(runnable, monitor);
+			}
+		};
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#run(java.lang.String, boolean, org.eclipse.jface.operation.IRunnableWithProgress)
+	 */
+	public void run(String title, ISchedulingRule schedulingRule, boolean postponeBuild, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
+		Job job;
+		if (schedulingRule == null && !postponeBuild) {
+			job = getBasicJob(title, runnable);
+		} else {
+			job = getWorkspaceJob(title, runnable);
+			if (schedulingRule != null) {
+				job.setRule(schedulingRule);
+			}
+		}
+		if (listener != null) {
+			job.addJobChangeListener(listener);
+		}
+		schedule(job);
+	}
+
+	protected void schedule(Job job) {
+		job.schedule();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.ICVSRunnableContext#getShell()
+	 */
+	public Shell getShell() {
+		final Shell[] newShell = new Shell[] { null };
+		Display.getDefault().syncExec(
+			new Runnable() {
+				public void run() {
+					IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+					if (window == null) {
+						Display display = Display.getDefault();
+						newShell[0] = new Shell(display);
+					} else {
+						newShell[0] = window.getShell();
+					}
+				}
+			});
+		return newShell[0];
+	}
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java
new file mode 100644
index 0000000..f0cd4b5
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/CVSSubscriberNonblockingContext.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui.operations;
+
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.team.internal.ui.jobs.JobStatusHandler;
+import org.eclipse.team.ui.sync.SubscriberAction;
+
+/**
+ * This context uses the JobStatusHandler from SubscriberAction to ensure
+ * proper busy indication in the sync view.
+ */
+public class CVSSubscriberNonblockingContext extends CVSNonblockingRunnableContext {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSNonblockingRunnableContext#schedule(org.eclipse.core.runtime.jobs.Job)
+	 */
+	protected void schedule(Job job) {
+		JobStatusHandler.schedule(job, SubscriberAction.SUBSCRIBER_JOB_TYPE);
+	}
+
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java
new file mode 100644
index 0000000..8f3de3d
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/FetchMembersOperation.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui.operations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.progress.IElementCollector;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.sync.IRemoteResource;
+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.ICVSRemoteFolder;
+import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderMemberFetcher;
+import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
+import org.eclipse.team.internal.ccvs.ui.Policy;
+
+/**
+ * Fetch the members of a remote folder in the background, passing incremental
+ * results through an IElementCollector.
+ */
+public class FetchMembersOperation extends RemoteOperation {
+
+	/* internal uzse only */ IElementCollector collector;
+	/* internal uzse only */ RemoteFolderFilter filter = new RemoteFolderFilter();
+	
+	public static class RemoteFolderFilter {
+		public ICVSRemoteResource[] filter(ICVSRemoteResource[] resource) {
+			return resource;
+		}
+	}
+	
+	public class InternalRemoteFolderMemberFetcher extends RemoteFolderMemberFetcher {
+		long sendIncrement = 100;
+		List unsent = new ArrayList();
+		long intervalStart;
+		protected InternalRemoteFolderMemberFetcher(RemoteFolder parentFolder, CVSTag tag) {
+			super(parentFolder, tag);
+		}
+		protected void parentDoesNotExist() {
+			super.parentDoesNotExist();
+			// Indicate that there are no children
+			collector.add(new Object[0], getProgressMonitor());
+		}
+		protected RemoteFolder recordFolder(String name) {
+			RemoteFolder folder = super.recordFolder(name);
+			unsent.add(folder);
+			if (isTimeToSend()) {
+				sendFolders();
+			}
+			return folder;
+		}
+		private boolean isTimeToSend() {
+			long currentTime = System.currentTimeMillis();
+			return (currentTime - intervalStart) >  sendIncrement;
+		}
+		protected IStatus performUpdate(IProgressMonitor progress, CVSTag tag) throws CVSException {
+			intervalStart = System.currentTimeMillis();
+			IStatus status = super.performUpdate(progress, tag);
+			sendFolders();
+			return status;
+		}
+		protected void updateFileRevisions(ICVSFile[] files, IProgressMonitor monitor) throws CVSException {
+			super.updateFileRevisions(files, monitor);
+			sendFiles();
+		}
+		private void sendFolders() {
+			updateParentFolderChildren();
+			collector.add(filter.filter((ICVSRemoteFolder[]) unsent.toArray(new ICVSRemoteFolder[unsent.size()])), getProgressMonitor());
+			unsent.clear();
+			intervalStart = System.currentTimeMillis();
+		}
+		private void sendFiles() {
+			collector.add(getFiles(), getProgressMonitor());
+			unsent.clear();
+		}
+		private IProgressMonitor getProgressMonitor() {
+			return null;
+		}
+	}
+
+	public FetchMembersOperation(Shell shell, ICVSRemoteFolder folder, IElementCollector collector) {
+		super(shell, new ICVSRemoteResource[] { folder });
+		this.collector = collector;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	protected void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
+		ICVSRemoteFolder remote = getRemoteFolder();
+		if (remote.getClass().equals(RemoteFolder.class)) {
+			monitor = Policy.monitorFor(monitor);
+			boolean isRoot = remote.getName().equals(ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME);
+			monitor.beginTask(null, 100 + (isRoot ? 30 : 0));
+			RemoteFolderMemberFetcher fetcher = new InternalRemoteFolderMemberFetcher((RemoteFolder)remote, remote.getTag());
+			fetcher.fetchMembers(Policy.subMonitorFor(monitor, 100));
+			if (isRoot) {
+				ICVSRemoteResource[] modules = CVSUIPlugin.getPlugin()
+					.getRepositoryManager()
+					.getRepositoryRootFor(remote.getRepository())
+					.getDefinedModules(remote.getTag(), Policy.subMonitorFor(monitor, 25));
+				collector.add(filter.filter(modules), Policy.subMonitorFor(monitor, 5));
+			}
+		} else {
+			monitor = Policy.monitorFor(monitor);
+			try {
+				monitor.beginTask(null, 100);
+				IRemoteResource[] children = remote.members(Policy.subMonitorFor(monitor, 95));
+				collector.add(children, Policy.subMonitorFor(monitor, 5));
+			} catch (TeamException e) {
+				throw CVSException.wrapException(e);
+			} finally {
+				monitor.done();
+			}
+		}
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName()
+	 */
+	protected String getTaskName() {
+		return Policy.bind("FetchMembersOperation.0", getRemoteFolder().getName()); //$NON-NLS-1$
+	}
+
+	private ICVSRemoteFolder getRemoteFolder() {
+		return (ICVSRemoteFolder)getRemoteResources()[0];
+	}
+
+	public RemoteFolderFilter getFilter() {
+		return filter;
+	}
+
+	public void setFilter(RemoteFolderFilter filter) {
+		this.filter = filter;
+	}
+
+}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java
new file mode 100644
index 0000000..64adcea
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ICVSRunnableContext.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.team.internal.ccvs.ui.operations;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * An ICVSRunnableContext is used to provide the context for a CVS operation.
+ * The hierarchy of contexts is used to configure the following:
+ * 1) whether the operation is run in the background as a job
+ * 2) whether the operation modifies the workspace
+ * 3) what shell the operation should use to display info to the user
+ */
+public interface ICVSRunnableContext {
+	
+	/**
+	 * Run the given runnable in the context of the receiver. By default, the
+	 * progress is provided by the active workbench windows but subclasses may
+	 * override this to provide progress in some other way (Progress Monitor or
+	 * job).
+	 */
+	public abstract void run(
+		String title,
+		ISchedulingRule schedulingRule,
+		boolean postponeBuild, 
+		IRunnableWithProgress runnable)
+		throws InvocationTargetException, InterruptedException;
+		
+	/**
+	 * Get a shell that can be used to prompt the user.
+	 * @return a shell
+	 */
+	public abstract Shell getShell();
+}
\ No newline at end of file