https://bugs.eclipse.org/bugs/show_bug.cgi?id=264338
diff --git a/org.eclipse.core.externaltools/META-INF/MANIFEST.MF b/org.eclipse.core.externaltools/META-INF/MANIFEST.MF
index dea5ba1..7685f18 100644
--- a/org.eclipse.core.externaltools/META-INF/MANIFEST.MF
+++ b/org.eclipse.core.externaltools/META-INF/MANIFEST.MF
@@ -3,10 +3,10 @@
 Bundle-Name: %pluginName
 Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.core.externaltools;singleton:=true
-Bundle-Version: 1.0.0.qualifier
+Bundle-Version: 0.0.9.qualifier
 Bundle-Activator: org.eclipse.core.externaltools.internal.ExternalToolsCore
-Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.debug.core;bundle-version="[3.6.0,4.0.0)",
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.debug.core;bundle-version="[3.4.2,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.2.0,4.0.0)"
 Bundle-RequiredExecutionEnvironment: J2SE-1.4
 Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/model/BuilderCoreUtils.java b/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/model/BuilderCoreUtils.java
index f3b7acd..12cdff9 100644
--- a/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/model/BuilderCoreUtils.java
+++ b/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/model/BuilderCoreUtils.java
@@ -266,7 +266,8 @@
 		if (!status.isOK()) {
 			name = "ExternalTool"; //$NON-NLS-1$
 		}
-		name = DebugPlugin.getDefault().getLaunchManager().generateLaunchConfigurationName(name);
+		name = DebugPlugin.getDefault().getLaunchManager()
+				.generateUniqueLaunchConfigurationNameFrom(name);
 		workingCopy.rename(name);
 		return workingCopy.doSave();
 	}
diff --git a/org.eclipse.debug.core/.settings/.api_filters b/org.eclipse.debug.core/.settings/.api_filters
new file mode 100644
index 0000000..e75dabb
--- /dev/null
+++ b/org.eclipse.debug.core/.settings/.api_filters
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component id="org.eclipse.debug.core" version="2">
+    <resource path="core/org/eclipse/debug/core/ILaunchManager.java" type="org.eclipse.debug.core.ILaunchManager">
+        <filter id="1209008130">
+            <message_arguments>
+                <message_argument value="3.6"/>
+                <message_argument value="3.4"/>
+                <message_argument value="org.eclipse.debug.core.ILaunchManager"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="core/org/eclipse/debug/core/RefreshUtil.java" type="org.eclipse.debug.core.RefreshUtil">
+        <filter id="1108344834">
+            <message_arguments>
+                <message_argument value="3.6"/>
+                <message_argument value="3.4"/>
+                <message_argument value="org.eclipse.debug.core.RefreshUtil"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="META-INF/MANIFEST.MF">
+        <filter id="924844039">
+            <message_arguments>
+                <message_argument value="3.4.2.qualifier"/>
+                <message_argument value="3.4.0.v20080612"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
diff --git a/org.eclipse.debug.core/META-INF/MANIFEST.MF b/org.eclipse.debug.core/META-INF/MANIFEST.MF
index 072b5d5..b2c9d5d 100644
--- a/org.eclipse.debug.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.debug.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.debug.core; singleton:=true
-Bundle-Version: 3.4.1.qualifier
+Bundle-Version: 3.4.2.qualifier
 Bundle-ClassPath: .
 Bundle-Activator: org.eclipse.debug.core.DebugPlugin
 Bundle-Vendor: %providerName
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java
index efb35b0..cc704c4 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -43,6 +43,16 @@
 	 * @since 3.0
 	 */
 	public static final String PROFILE_MODE= "profile"; //$NON-NLS-1$	
+
+	/**
+	 * Launch configuration attribute - a boolean value that indicates if the
+	 * launch configuration is 'private'. A private configuration is one that
+	 * does not appear in the user interface (launch history or the launch
+	 * configuration dialog).
+	 * 
+	 * @since 3.6
+	 */
+	public static final String ATTR_PRIVATE = "org.eclipse.debug.ui.private"; //$NON-NLS-1$
 	
 	/**
 	 * Launch configuration attribute name. The value is a map of environment
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/core/RefreshUtil.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/RefreshUtil.java
new file mode 100644
index 0000000..2c516a2
--- /dev/null
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/RefreshUtil.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.variables.IStringVariableManager;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.debug.internal.core.DebugCoreMessages;
+import org.eclipse.debug.internal.core.IMementoConstants;
+import org.eclipse.debug.internal.core.ResourceFactory;
+import org.eclipse.debug.internal.core.XMLMemento;
+
+import com.ibm.icu.text.MessageFormat;
+
+/**
+ * Utilities for launch configurations that persist, restore, and refresh
+ * collections of resources.
+ * 
+ * @since 3.6
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class RefreshUtil {
+
+	/**
+	 * String attribute identifying a scope of resources that should be
+	 * refreshed - for example, after an external tool is run. The value is either
+	 * a resource memento constant by this class, a resource memento created
+	 * via {@link RefreshUtil#toMemento(IResource[])}, <code>null</code>, indicating no
+	 * refresh.
+	 */
+	public static final String ATTR_REFRESH_SCOPE = DebugPlugin.getUniqueIdentifier() + ".ATTR_REFRESH_SCOPE"; //$NON-NLS-1$
+
+	/**
+	 * Boolean attribute indicating if a refresh scope is recursive. Default
+	 * value is <code>true</code>. When a refresh is recursive, resources are
+	 * refreshed to an infinite depth, otherwise they are refreshed to a depth
+	 * of one.
+	 */
+	public static final String ATTR_REFRESH_RECURSIVE = DebugPlugin.getUniqueIdentifier() + ".ATTR_REFRESH_RECURSIVE"; //$NON-NLS-1$
+	
+	/**
+	 * Resource memento referring to the selected resource's project.
+	 * Only works when the debug user interface is running.
+	 * 
+	 * @see #toResources(String)
+	 */
+	public static final String MEMENTO_SELECTED_PROJECT = "${project}"; //$NON-NLS-1$
+	
+	/**
+	 * Resource memento referring to the selected resource's container.
+	 * Only works when the debug user interface is running.
+	 * 
+	 * @see #toResources(String)
+	 */	
+	public static final String MEMENTO_SELECTED_CONTAINER = "${container}"; //$NON-NLS-1$
+	
+	/**
+	 * Resource memento referring to the selected resource.
+	 * Only works when the debug user interface is running.
+	 * 
+	 * @see #toResources(String)
+	 */	
+	public static final String MEMENTO_SELECTED_RESOURCE = "${resource}"; //$NON-NLS-1$
+	
+	/**
+	 * Resource memento referring to the workspace root.
+	 * 
+	 * @see #toResources(String)
+	 */	
+	public static final String MEMENTO_WORKSPACE = "${workspace}"; //$NON-NLS-1$
+	
+	/**
+	 *  Indicates no working set has been selected (for backwards compatibility).
+	 *  The new format uses an empty working set
+	 */
+	
+	private static final String NO_WORKING_SET = "NONE"; //$NON-NLS-1$
+
+	/**
+	 * Refreshes the resources as specified by the given launch configuration.
+	 * 
+	 * @param resources
+	 *            resources to refresh
+	 * @param depth one of {@link IResource#DEPTH_INFINITE}, {@link IResource#DEPTH_ONE},
+	 *  or {@link IResource#DEPTH_ZERO} 
+	 * @param monitor
+	 *            progress monitor which may be <code>null</code>
+	 * @throws CoreException
+	 *             if an exception occurs while refreshing resources
+	 */
+	public static void refreshResources(IResource[] resources, int depth, IProgressMonitor monitor) throws CoreException {
+		if (monitor == null) {
+			monitor = new NullProgressMonitor();
+		}
+		if (resources == null || resources.length == 0) {
+			return;
+		}
+		if (monitor.isCanceled()) {
+			return;
+		}
+		monitor.beginTask(DebugCoreMessages.RefreshingResources, resources.length);
+		MultiStatus status = new MultiStatus(DebugPlugin.getUniqueIdentifier(), 0, DebugCoreMessages.RefreshingResourcesError, null);
+		for (int i = 0; i < resources.length; i++) {
+			if (monitor.isCanceled())
+				break;
+			if (resources[i] != null && resources[i].isAccessible()) {
+				try {
+					resources[i].refreshLocal(depth, null);
+				} catch (CoreException e) {
+					status.merge(e.getStatus());
+				}
+			}
+			monitor.worked(1);
+		}
+		monitor.done();
+		if (!status.isOK()) {
+			throw new CoreException(status);
+		}
+	}
+
+	/**
+	 * Returns a collection of resources referred to by the specified
+	 * memento generated via {@link #toMemento(IResource[])}.
+	 * 
+	 * @param memento
+	 *            resource memento generated by this manager
+	 * @return collection of resources referred to by the memento
+	 * @throws CoreException
+	 *             if unable to resolve a set of resources
+	 */
+	public static IResource[] toResources(String memento) throws CoreException {
+		if (memento.startsWith("${resource:")) { //$NON-NLS-1$
+			// This is an old format that is replaced with 'working_set'
+			String pathString = memento.substring(11, memento.length() - 1);
+			Path path = new Path(pathString);
+			IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
+			if (resource == null) {
+				throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
+						IStatus.ERROR, MessageFormat.format(DebugCoreMessages.RefreshUtil_1,
+								new String[] { pathString }), null));
+			}
+			return new IResource[] { resource };
+		} else if (memento.startsWith("${working_set:")) { //$NON-NLS-1$
+			String ws = memento.substring(14, memento.length() - 1);
+			return getResources(ws);
+		} else if (memento.equals(MEMENTO_WORKSPACE)) {
+			return new IResource[] { ResourcesPlugin.getWorkspace().getRoot() };
+		} else {
+			// result the selected resource for backwards compatibility
+			IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
+			IResource resource = null;
+			try {
+				String pathString = manager.performStringSubstitution("${selected_resource_path}"); //$NON-NLS-1$
+				resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(pathString));
+			} catch (CoreException e) {
+				// unable to resolve a resource
+			}
+			if (resource == null) {
+				// empty selection
+				return new IResource[]{};
+			} else {
+				if (memento.equals(MEMENTO_SELECTED_RESOURCE)) {
+					return new IResource[] { resource };
+				} else if (memento.equals(MEMENTO_SELECTED_CONTAINER)) {
+					return new IResource[] {resource.getParent()};
+				} else if (memento.equals(MEMENTO_SELECTED_PROJECT)) {
+					return new IResource[] {resource.getProject()};
+				}
+			}
+		}
+		throw new CoreException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), MessageFormat.format(DebugCoreMessages.RefreshUtil_0, new String[]{memento})));
+	}
+	
+	/**
+	 * Returns a memento for a collection of resources that can be restored
+	 * via {@link #toResources(String)}.
+	 * 
+	 * @param resources resources to create a memento for
+	 * @return memento for the given resources
+	 */
+	public static String toMemento(IResource[] resources) {
+		XMLMemento memento = XMLMemento.createWriteRoot("resources"); //$NON-NLS-1$
+		for (int i = 0; i < resources.length; i++) {
+			final XMLMemento itemMemento = memento.createChild(IMementoConstants.MEMENTO_ITEM);
+			ResourceFactory.saveState(itemMemento, resources[i]);
+		}
+		StringWriter writer = new StringWriter();
+		try {
+			memento.save(writer);
+		} catch (IOException e) {
+			DebugPlugin.log(e);
+		}
+		StringBuffer buf = new StringBuffer();
+		buf.append("${working_set:"); //$NON-NLS-1$
+		buf.append(writer.toString());
+		buf.append("}"); //$NON-NLS-1$
+		return buf.toString();
+	}
+	
+	/**
+	 * Restores a collection of resources from a working set memento, for backwards
+	 * compatibility.
+	 * 
+	 * @param wsMemento working set memento
+	 * @return resource collection, possibly empty
+	 */
+	private static IResource[] getResources(String wsMemento) {
+
+		if (NO_WORKING_SET.equals(wsMemento)) {
+			return null;
+		}
+
+		List resourcesList = new ArrayList();
+		StringReader reader = new StringReader(wsMemento);
+
+		XMLMemento memento = null;
+		try {
+			memento = XMLMemento.createReadRoot(reader);
+		} catch (Exception e) {
+			DebugPlugin.log(e);
+			return null;
+		}
+
+		XMLMemento[] mementos = memento
+				.getChildren(IMementoConstants.MEMENTO_ITEM);
+		for (int i = 0; i < mementos.length; i++) {
+			resourcesList.add(ResourceFactory.createElement(mementos[i]));
+		}
+
+		return (IResource[]) resourcesList.toArray(new IResource[resourcesList.size()]);
+
+	}	
+	
+	/**
+	 * Returns whether the refresh scope specified by the given launch
+	 * configuration is recursive.
+	 * 
+	 * @param configuration
+	 * @return whether the refresh scope is recursive
+	 * @throws CoreException
+	 *             if unable to access the associated attribute
+	 */
+	public static  boolean isRefreshRecursive(ILaunchConfiguration configuration) throws CoreException {
+		return configuration.getAttribute(ATTR_REFRESH_RECURSIVE, true);
+	}	
+	
+	/**
+	 * Refreshes the resources as specified by the given launch configuration via its
+	 * {@link RefreshUtil#ATTR_REFRESH_SCOPE} and {@link #ATTR_REFRESH_RECURSIVE} attributes.
+	 * 
+	 * @param configuration launch configuration
+	 * @param monitor progress monitor which may be <code>null</code>
+	 * @throws CoreException
+	 *             if an exception occurs while refreshing resources or accessing launch
+	 *             configuration attributes
+	 */
+	public static void refreshResources(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
+		String scope = configuration.getAttribute(ATTR_REFRESH_SCOPE, (String) null);
+		if (scope != null) {
+			IResource[] resources = toResources(scope);
+			if (resources != null && resources.length > 0) {
+				int depth = IResource.DEPTH_ONE;
+				if (isRefreshRecursive(configuration)) {
+					depth = IResource.DEPTH_INFINITE;
+				}
+				refreshResources(resources, depth, monitor);
+			}
+		}
+	}	
+}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java
index a8ade0a..c823200 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.java
@@ -127,6 +127,13 @@
 	public static String RuntimeProcess_Exit_value_not_available_until_process_terminates__1;
 	public static String WatchExpression_0;
 	public static String NullStreamsProxy_0;
+	
+	public static String RefreshingResources;
+	public static String RefreshingResourcesError;
+
+	public static String RefreshUtil_0;
+
+	public static String RefreshUtil_1;
 
 	static {
 		// load message values from bundle file
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties
index c169c7f..6416b91 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/DebugCoreMessages.properties
@@ -99,3 +99,7 @@
 WatchExpression_0=(Watch expressions not supported)
 NullStreamsProxy_0=Null Stream Monitor
 J9VMRunner_0=Exception occurred executing command line.
+RefreshingResources=Refresh resources...
+RefreshingResourcesError=Exception(s) occurred during refresh.
+RefreshUtil_0=Unable to restore resource memento: {0}
+RefreshUtil_1=Refresh scope refers to non-existent resource {0}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IMementoConstants.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IMementoConstants.java
new file mode 100644
index 0000000..ed9f1e8
--- /dev/null
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IMementoConstants.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.internal.core;
+
+public interface IMementoConstants {
+	// These persistence constant is stored in XML. Do not
+	// change it.
+	public static final String TAG_FACTORY_ID = "factoryID"; //$NON-NLS-1$
+	
+	public static final String TAG_EDITOR_STATE = "editorState"; //$NON-NLS-1$
+
+	public static final String MEMENTO_ITEM = "item"; //$NON-NLS-1$
+
+	public static final String TAG_EDIT_PAGE_ID = "editPageId"; //$NON-NLS-1$
+
+	public static final String TAG_NAME = "name"; //$NON-NLS-1$
+
+	public static final String TAG_LABEL = "label"; //$NON-NLS-1$
+
+	public static final String TAG_ID = "id"; //$NON-NLS-1$
+
+	public static final String TAG_LAUNCH_CONFIGURATION_WORKING_SET = "launchConfigurationWorkingSet"; //$NON-NLS-1$
+
+}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/ResourceFactory.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/ResourceFactory.java
new file mode 100644
index 0000000..789cdd9
--- /dev/null
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/ResourceFactory.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.internal.core;
+
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * The ResourceFactory is used to save and recreate an IResource object.
+ * As such, it implements the IPersistableElement interface for storage
+ * and the IElementFactory interface for recreation.
+ */
+public class ResourceFactory {
+
+    // These persistence constants are stored in XML.  Do not
+    // change them.
+    public static final String TAG_PATH = "path";//$NON-NLS-1$
+
+    public static final String TAG_TYPE = "type";//$NON-NLS-1$
+
+    /**
+     * Creates and returns an element based on the given memento
+     * 
+     * @param memento element memento
+     * @return associated element
+     */
+    public static IAdaptable createElement(XMLMemento memento) {
+        // Get the file name.
+        String fileName = memento.getString(TAG_PATH);
+        if (fileName == null) {
+			return null;
+		}
+
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+        String type = memento.getString(TAG_TYPE);
+        IResource res = null;
+        if (type == null) {
+            // Old format memento. Create an IResource using findMember. 
+            // Will return null for resources in closed projects.
+            res = root.findMember(new Path(fileName));
+        } else {
+            int resourceType = Integer.parseInt(type);
+
+            if (resourceType == IResource.ROOT) {
+				res = root;
+			} else if (resourceType == IResource.PROJECT) {
+				res = root.getProject(fileName);
+			} else if (resourceType == IResource.FOLDER) {
+				res = root.getFolder(new Path(fileName));
+			} else if (resourceType == IResource.FILE) {
+				res = root.getFile(new Path(fileName));
+			}
+        }
+        return res;
+    }
+
+    public static void saveState(XMLMemento memento, IResource res) {
+        memento.putString(TAG_PATH, res.getFullPath().toString());
+        memento.putString(TAG_TYPE, Integer.toString(res.getType()));
+    }
+}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/XMLMemento.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/XMLMemento.java
new file mode 100644
index 0000000..6daf965
--- /dev/null
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/XMLMemento.java
@@ -0,0 +1,599 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.internal.core;
+
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.debug.core.DebugPlugin;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * An XML memento. Copied from workspace plug-in.
+ */
+public final class XMLMemento {
+    private Document factory;
+
+    private Element element;
+
+    /**
+     * Creates a <code>Document</code> from the <code>Reader</code>
+     * and returns a memento on the first <code>Element</code> for reading
+     * the document.
+     * <p>
+     * Same as calling createReadRoot(reader, null)
+     * </p>
+     * 
+     * @param reader the <code>Reader</code> used to create the memento's document
+     * @return a memento on the first <code>Element</code> for reading the document
+     * @throws Exception if IO problems, invalid format, or no element.
+     */
+    public static XMLMemento createReadRoot(Reader reader)
+            throws Exception {
+        return createReadRoot(reader, null);
+    }
+
+    /**
+     * Creates a <code>Document</code> from the <code>Reader</code>
+     * and returns a memento on the first <code>Element</code> for reading
+     * the document.
+     * 
+     * @param reader the <code>Reader</code> used to create the memento's document
+     * @param baseDir the directory used to resolve relative file names
+     * 		in the XML document. This directory must exist and include the
+     * 		trailing separator. The directory format, including the separators,
+     * 		must be valid for the platform. Can be <code>null</code> if not
+     * 		needed.
+     * @return a memento on the first <code>Element</code> for reading the document
+     * @throws Exception if IO problems, invalid format, or no element.
+     */
+    public static XMLMemento createReadRoot(Reader reader, String baseDir)
+            throws Exception {
+        String errorMessage = null;
+        Exception exception = null;
+
+        try {
+            DocumentBuilderFactory factory = DocumentBuilderFactory
+                    .newInstance();
+            DocumentBuilder parser = factory.newDocumentBuilder();
+            InputSource source = new InputSource(reader);
+            if (baseDir != null) {
+				source.setSystemId(baseDir);
+			}
+            Document document = parser.parse(source);
+            NodeList list = document.getChildNodes();
+            for (int i = 0; i < list.getLength(); i++) {
+                Node node = list.item(i);
+                if (node instanceof Element) {
+					return new XMLMemento(document, (Element) node);
+				}
+            }
+        } catch (ParserConfigurationException e) {
+            exception = e;
+           // errorMessage = WorkbenchMessages.XMLMemento_parserConfigError;
+        } catch (IOException e) {
+            exception = e;
+           // errorMessage = WorkbenchMessages.XMLMemento_ioError; 
+        } catch (SAXException e) {
+            exception = e;
+           // errorMessage = WorkbenchMessages.XMLMemento_formatError; 
+        }
+
+        String problemText = null;
+        if (exception != null) {
+			problemText = exception.getMessage();
+		}
+        if (problemText == null || problemText.length() == 0) {
+			problemText = errorMessage != null ? errorMessage
+                    :"ERROR"; //;WorkbenchMessages.XMLMemento_noElement; //$NON-NLS-1$
+		} 
+        throw new Exception(problemText, exception);
+    }
+
+    /**
+     * Returns a root memento for writing a document.
+     * 
+     * @param type the element node type to create on the document
+     * @return the root memento for writing a document
+     */
+    public static XMLMemento createWriteRoot(String type) {
+        Document document;
+        try {
+            document = DocumentBuilderFactory.newInstance()
+                    .newDocumentBuilder().newDocument();
+            Element element = document.createElement(type);
+            document.appendChild(element);
+            return new XMLMemento(document, element);
+        } catch (ParserConfigurationException e) {
+//            throw new Error(e);
+            throw new Error(e.getMessage());
+        }
+    }
+
+    /**
+     * Creates a memento for the specified document and element.
+     * <p>
+     * Clients should use <code>createReadRoot</code> and
+     * <code>createWriteRoot</code> to create the initial
+     * memento on a document.
+     * </p>
+     * 
+     * @param document the document for the memento
+     * @param element the element node for the memento
+     */
+    public XMLMemento(Document document, Element element) {
+        super();
+        this.factory = document;
+        this.element = element;
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public XMLMemento createChild(String type) {
+        Element child = factory.createElement(type);
+        element.appendChild(child);
+        return new XMLMemento(factory, child);
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public XMLMemento createChild(String type, String id) {
+        Element child = factory.createElement(type);
+        child.setAttribute(IMementoConstants.TAG_ID, id == null ? "" : id); //$NON-NLS-1$
+        element.appendChild(child);
+        return new XMLMemento(factory, child);
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public XMLMemento copyChild(XMLMemento child) {
+        Element childElement = child.element;
+        Element newElement = (Element) factory.importNode(childElement, true);
+        element.appendChild(newElement);
+        return new XMLMemento(factory, newElement);
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public XMLMemento getChild(String type) {
+
+        // Get the nodes.
+        NodeList nodes = element.getChildNodes();
+        int size = nodes.getLength();
+        if (size == 0) {
+			return null;
+		}
+
+        // Find the first node which is a child of this node.
+        for (int nX = 0; nX < size; nX++) {
+            Node node = nodes.item(nX);
+            if (node instanceof Element) {
+                Element element1 = (Element) node;
+                if (element1.getNodeName().equals(type)) {
+					return new XMLMemento(factory, element1);
+				}
+            }
+        }
+
+        // A child was not found.
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public XMLMemento[] getChildren(String type) {
+
+        // Get the nodes.
+        NodeList nodes = element.getChildNodes();
+        int size = nodes.getLength();
+        if (size == 0) {
+			return new XMLMemento[0];
+		}
+
+        // Extract each node with given type.
+        ArrayList list = new ArrayList(size);
+        for (int nX = 0; nX < size; nX++) {
+            Node node = nodes.item(nX);
+            if (node instanceof Element) {
+                Element element1 = (Element) node;
+                if (element1.getNodeName().equals(type)) {
+					list.add(element1);
+				}
+            }
+        }
+
+        // Create a memento for each node.
+        size = list.size();
+        XMLMemento[] results = new XMLMemento[size];
+        for (int x = 0; x < size; x++) {
+            results[x] = new XMLMemento(factory, (Element) list.get(x));
+        }
+        return results;
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public Float getFloat(String key) {
+        Attr attr = element.getAttributeNode(key);
+        if (attr == null) {
+			return null;
+		}
+        String strValue = attr.getValue();
+        try {
+            return new Float(strValue);
+        } catch (NumberFormatException e) {
+           DebugPlugin.logMessage("Memento problem - Invalid float for key: " //$NON-NLS-1$
+                    + key + " value: " + strValue, e); //$NON-NLS-1$
+            return null;
+        }
+    }
+
+	public String getType() {
+		return element.getNodeName();
+	}
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public String getID() {
+        return element.getAttribute(IMementoConstants.TAG_ID);
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public Integer getInteger(String key) {
+        Attr attr = element.getAttributeNode(key);
+        if (attr == null) {
+			return null;
+		}
+        String strValue = attr.getValue();
+        try {
+            return new Integer(strValue);
+        } catch (NumberFormatException e) {
+            DebugPlugin
+                    .logMessage("Memento problem - invalid integer for key: " + key //$NON-NLS-1$
+                            + " value: " + strValue, e); //$NON-NLS-1$
+            return null;
+        }
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public String getString(String key) {
+        Attr attr = element.getAttributeNode(key);
+        if (attr == null) {
+			return null;
+		}
+        return attr.getValue();
+    }
+
+	public Boolean getBoolean(String key) {
+        Attr attr = element.getAttributeNode(key);
+        if (attr == null) {
+			return null;
+		}
+        return Boolean.valueOf(attr.getValue());
+	}
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public String getTextData() {
+        Text textNode = getTextNode();
+        if (textNode != null) {
+            return textNode.getData();
+        }
+        return null;
+    }
+
+	public String[] getAttributeKeys() {
+		NamedNodeMap map = element.getAttributes();
+		int size = map.getLength();
+		String[] attributes = new String[size];
+		for (int i = 0; i < size; i++) {
+			Node node = map.item(i);
+			attributes[i] = node.getNodeName();
+		}
+		return attributes;
+	}
+
+    /**
+     * Returns the Text node of the memento. Each memento is allowed only 
+     * one Text node.
+     * 
+     * @return the Text node of the memento, or <code>null</code> if
+     * the memento has no Text node.
+     */
+    private Text getTextNode() {
+        // Get the nodes.
+        NodeList nodes = element.getChildNodes();
+        int size = nodes.getLength();
+        if (size == 0) {
+			return null;
+		}
+        for (int nX = 0; nX < size; nX++) {
+            Node node = nodes.item(nX);
+            if (node instanceof Text) {
+                return (Text) node;
+            }
+        }
+        // a Text node was not found
+        return null;
+    }
+
+    /**
+     * Places the element's attributes into the document.
+     * @param copyText true if the first text node should be copied
+     */
+    private void putElement(Element element1, boolean copyText) {
+        NamedNodeMap nodeMap = element1.getAttributes();
+        int size = nodeMap.getLength();
+        for (int i = 0; i < size; i++) {
+            Attr attr = (Attr) nodeMap.item(i);
+            putString(attr.getName(), attr.getValue());
+        }
+
+        NodeList nodes = element1.getChildNodes();
+        size = nodes.getLength();
+        // Copy first text node (fixes bug 113659).
+        // Note that text data will be added as the first child (see putTextData)
+        boolean needToCopyText = copyText;
+        for (int i = 0; i < size; i++) {
+            Node node = nodes.item(i);
+            if (node instanceof Element) {
+                XMLMemento child = createChild(node.getNodeName());
+                child.putElement((Element) node, true);
+            } else if (node instanceof Text && needToCopyText) {
+                putTextData(((Text) node).getData());
+                needToCopyText = false;
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public void putFloat(String key, float f) {
+        element.setAttribute(key, String.valueOf(f));
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public void putInteger(String key, int n) {
+        element.setAttribute(key, String.valueOf(n));
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public void putMemento(XMLMemento memento) {
+    	// Do not copy the element's top level text node (this would overwrite the existing text).
+    	// Text nodes of children are copied.
+        putElement(memento.element, false);
+    }
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public void putString(String key, String value) {
+        if (value == null) {
+			return;
+		}
+        element.setAttribute(key, value);
+    }
+
+	/**
+	 * @param key 
+	 * @param value 
+	 * @since 3.4
+	 */
+	public void putBoolean(String key, boolean value) {
+		element.setAttribute(key, value ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+    /* (non-Javadoc)
+     * Method declared in XMLMemento.
+     */
+    public void putTextData(String data) {
+        Text textNode = getTextNode();
+        if (textNode == null) {
+            textNode = factory.createTextNode(data);
+			// Always add the text node as the first child (fixes bug 93718) 
+			element.insertBefore(textNode, element.getFirstChild());
+        } else {
+            textNode.setData(data);
+        }
+    }
+
+    /**
+     * Saves this memento's document current values to the
+     * specified writer. 
+     * 
+     * @param writer the writer used to save the memento's document
+     * @throws IOException if there is a problem serializing the document to the stream.
+     */
+    public void save(Writer writer) throws IOException {
+    	DOMWriter out = new DOMWriter(writer);
+        try {
+        	out.print(element);
+    	} finally {
+    		out.close();
+    	}
+	}
+
+	/**
+     * A simple XML writer.  Using this instead of the javax.xml.transform classes allows
+     * compilation against JCL Foundation (bug 80053). 
+     */
+    private static final class DOMWriter extends PrintWriter {
+    	
+    	private int tab;
+
+    	/* constants */
+    	private static final String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$
+
+    	/**
+    	 * Creates a new DOM writer on the given output writer.
+    	 * 
+    	 * @param output the output writer
+    	 */
+    	public DOMWriter(Writer output) {
+    		super(output);
+    		tab = 0;
+    		println(XML_VERSION);
+    	}
+
+    	/**
+    	 * Prints the given element.
+    	 * 
+    	 * @param element the element to print
+    	 */
+        public void print(Element element) {
+        	// Ensure extra whitespace is not emitted next to a Text node,
+        	// as that will result in a situation where the restored text data is not the
+        	// same as the saved text data.
+        	boolean hasChildren = element.hasChildNodes();
+        	startTag(element, hasChildren);
+        	if (hasChildren) {
+	        	tab++;
+	        	boolean prevWasText = false;
+	        	NodeList children = element.getChildNodes();
+	    		for (int i = 0; i < children.getLength(); i++) {
+	    			Node node = children.item(i);
+	    			if (node instanceof Element) {
+	    				if (!prevWasText) {
+	    					println();
+	    					printTabulation();
+	    				}
+	    				print((Element) children.item(i));
+	    				prevWasText = false;
+	    			}
+	    			else if (node instanceof Text) {
+	    				print(getEscaped(node.getNodeValue()));
+	    				prevWasText = true;
+	    			}
+	    		}
+	    		tab--;
+	    		if (!prevWasText) {
+	    			println();
+	    			printTabulation();
+	    		}
+	    		endTag(element);
+        	}
+    	}
+
+    	private void printTabulation() {
+        	// Indenting is disabled, as it can affect the result of getTextData().
+        	// In 3.0, elements were separated by a newline but not indented.
+    		// This causes getTextData() to return "\n" even if no text data had explicitly been set.
+        	// The code here emulates that behaviour.
+    		
+//    		for (int i = 0; i < tab; i++)
+//    			super.print("\t"); //$NON-NLS-1$
+    	}
+
+    	private void startTag(Element element, boolean hasChildren) {
+    		StringBuffer sb = new StringBuffer();
+    		sb.append("<"); //$NON-NLS-1$
+    		sb.append(element.getTagName());
+    		NamedNodeMap attributes = element.getAttributes();
+   			for (int i = 0;  i < attributes.getLength(); i++) {
+   				Attr attribute = (Attr)attributes.item(i);
+				sb.append(" "); //$NON-NLS-1$
+				sb.append(attribute.getName());
+				sb.append("=\""); //$NON-NLS-1$
+				sb.append(getEscaped(String.valueOf(attribute.getValue())));
+				sb.append("\""); //$NON-NLS-1$
+   			}
+   			sb.append(hasChildren ? ">" : "/>"); //$NON-NLS-1$ //$NON-NLS-2$
+   			print(sb.toString());
+    	}
+
+    	private void endTag(Element element) {
+    		StringBuffer sb = new StringBuffer();
+    		sb.append("</"); //$NON-NLS-1$
+    		sb.append(element.getNodeName());
+    		sb.append(">"); //$NON-NLS-1$
+   			print(sb.toString());
+    	}
+    	
+    	private static void appendEscapedChar(StringBuffer buffer, char c) {
+    		String replacement = getReplacement(c);
+    		if (replacement != null) {
+    			buffer.append('&');
+    			buffer.append(replacement);
+    			buffer.append(';');
+    		} else if (c==9 || c==10 || c==13 || c>=32){
+    			buffer.append(c);
+    		}
+    	}
+
+    	private static String getEscaped(String s) {
+    		StringBuffer result = new StringBuffer(s.length() + 10);
+    		for (int i = 0; i < s.length(); ++i) {
+				appendEscapedChar(result, s.charAt(i));
+			}
+    		return result.toString();
+    	}
+
+    	private static String getReplacement(char c) {
+    		// Encode special XML characters into the equivalent character references.
+			// The first five are defined by default for all XML documents.
+			// The next three (#xD, #xA, #x9) are encoded to avoid them
+			// being converted to spaces on deserialization
+			// (fixes bug 93720)
+    		switch (c) {
+    			case '<' :
+    				return "lt"; //$NON-NLS-1$
+    			case '>' :
+    				return "gt"; //$NON-NLS-1$
+    			case '"' :
+    				return "quot"; //$NON-NLS-1$
+    			case '\'' :
+    				return "apos"; //$NON-NLS-1$
+    			case '&' :
+    				return "amp"; //$NON-NLS-1$
+				case '\r':
+					return "#x0D"; //$NON-NLS-1$
+				case '\n':
+					return "#x0A"; //$NON-NLS-1$
+				case '\u0009':
+					return "#x09"; //$NON-NLS-1$
+    		}
+    		return null;
+    	}
+    }
+}
diff --git a/org.eclipse.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.debug.ui/META-INF/MANIFEST.MF
index 705db40..cb54eed 100644
--- a/org.eclipse.debug.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.debug.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.debug.ui; singleton:=true
-Bundle-Version: 3.4.2.qualifier
+Bundle-Version: 3.4.3.qualifier
 Bundle-Activator: org.eclipse.debug.internal.ui.DebugUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.java
index 9a42a91..67f42ea 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.java
@@ -1,5 +1,5 @@
 /**********************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others. All rights reserved.   This
+ * Copyright (c) 2000, 2009 IBM Corporation and others. All rights reserved.   This
  * program and the accompanying materials are made available under the terms of
  * the Eclipse Public License v1.0 which accompanies this distribution, and is
  * available at http://www.eclipse.org/legal/epl-v10.html
@@ -20,6 +20,7 @@
 
 	public static String RefreshTab_0;
 
+	public static String RefreshTab_1;
 	public static String RefreshTab_43;
 
 	public static String RefreshTab_44;
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.properties b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.properties
index b0e3b8b..d478470 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.properties
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/stringsubstitution/StringSubstitutionMessages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2007 IBM Corporation and others.
+# Copyright (c) 2000, 2009 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -14,6 +14,7 @@
 PromptingResolver_0=Failed to expand {0}. Input was cancelled.
 
 RefreshTab_0=Recursively &include sub-folders
+RefreshTab_1=Working set
 RefreshTab_6=Refresh
 RefreshTab_7=Refresh resources...
 RefreshTab_8=Exception(s) occurred during refresh.
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/RefreshTab.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/RefreshTab.java
index 701331b..a35fc7a 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/RefreshTab.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/RefreshTab.java
@@ -1,39 +1,28 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
+ *  Copyright (c) 2000, 2009 IBM Corporation and others.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ * 
+ *  Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.debug.ui;
 
 
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import com.ibm.icu.text.MessageFormat;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.RefreshUtil;
 import org.eclipse.debug.internal.ui.DebugPluginImages;
 import org.eclipse.debug.internal.ui.DebugUIPlugin;
 import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
-import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
 import org.eclipse.debug.internal.ui.stringsubstitution.StringSubstitutionMessages;
 import org.eclipse.jface.window.Window;
 import org.eclipse.jface.wizard.WizardDialog;
@@ -49,8 +38,6 @@
 import org.eclipse.ui.IWorkingSet;
 import org.eclipse.ui.IWorkingSetManager;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.WorkbenchException;
-import org.eclipse.ui.XMLMemento;
 import org.eclipse.ui.dialogs.IWorkingSetEditWizard;
 
 /**
@@ -67,20 +54,17 @@
 
 	/**
 	 * Boolean attribute indicating if a refresh scope is recursive. Default
-	 * value is <code>false</code>.
+	 * value is <code>true</code>.
 	 */
-	public static final String ATTR_REFRESH_RECURSIVE = DebugPlugin.getUniqueIdentifier() + ".ATTR_REFRESH_RECURSIVE"; //$NON-NLS-1$
+	public static final String ATTR_REFRESH_RECURSIVE = RefreshUtil.ATTR_REFRESH_RECURSIVE;
 
 	/**
 	 * String attribute identifying the scope of resources that should be
 	 * refreshed after an external tool is run. The value is either a refresh
 	 * variable or the default value, <code>null</code>, indicating no refresh.
 	 */
-	public static final String ATTR_REFRESH_SCOPE = DebugPlugin.getUniqueIdentifier() + ".ATTR_REFRESH_SCOPE"; //$NON-NLS-1$
-	
-	// indicates no working set has been selected
-	private static final String NO_WORKING_SET = "NONE"; //$NON-NLS-1$
-	
+	public static final String ATTR_REFRESH_SCOPE = RefreshUtil.ATTR_REFRESH_SCOPE;
+		
 	// Check Buttons
 	private Button fRefreshButton;
 	private Button fRecursiveButton;
@@ -100,17 +84,6 @@
 	
 	// Working set
 	private IWorkingSet fWorkingSet;
-
-	/**
-	 * XML tag used to designate the root of the persisted IWorkingSet
-	 */
-	private static final String TAG_LAUNCH_CONFIGURATION_WORKING_SET= "launchConfigurationWorkingSet"; //$NON-NLS-1$
-
-	/**
-	 * XML tag used for setting / getting the factory ID of the persisted IWorkingSet
-	 * Bug 37143
-	 */	
-	private static final String TAG_FACTORY_ID = "factoryID"; //$NON-NLS-1$
 	
 	/**
 	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
@@ -269,13 +242,13 @@
 			// select the workspace by default
 			fWorkspaceButton.setSelection(true);
 		} else {
-			if (scope.equals("${workspace}")) { //$NON-NLS-1$
+			if (scope.equals(RefreshUtil.MEMENTO_WORKSPACE)) {
 				fWorkspaceButton.setSelection(true);
-			} else if (scope.equals("${resource}")) { //$NON-NLS-1$
+			} else if (scope.equals(RefreshUtil.MEMENTO_SELECTED_RESOURCE)) { 
 				fResourceButton.setSelection(true);
-			} else if (scope.equals("${container}")) { //$NON-NLS-1$
+			} else if (scope.equals(RefreshUtil.MEMENTO_SELECTED_CONTAINER)) { 
 				fContainerButton.setSelection(true);
-			} else if (scope.equals("${project}")) { //$NON-NLS-1$
+			} else if (scope.equals(RefreshUtil.MEMENTO_SELECTED_PROJECT)) { 
 				fProjectButton.setSelection(true);
 			} else if (scope.startsWith("${resource:")) { //$NON-NLS-1$
 				fWorkingSetButton.setSelection(true);
@@ -288,8 +261,7 @@
 				}
 			} else if (scope.startsWith("${working_set:")) { //$NON-NLS-1$
 				fWorkingSetButton.setSelection(true);
-				String memento = scope.substring(14, scope.length() - 1);
-				fWorkingSet = restoreWorkingSet(memento);
+				fWorkingSet = getWorkingSet(scope);
 			}
 		}
 	}
@@ -343,16 +315,16 @@
 	 */
 	private String generateScopeMemento() {
 		if (fWorkspaceButton.getSelection()) {
-			return "${workspace}"; //$NON-NLS-1$
+			return RefreshUtil.MEMENTO_WORKSPACE;
 		}
 		if (fResourceButton.getSelection()) {
-			return "${resource}"; //$NON-NLS-1$
+			return RefreshUtil.MEMENTO_SELECTED_RESOURCE;
 		}
 		if (fContainerButton.getSelection()) {
-			return "${container}"; //$NON-NLS-1$
+			return RefreshUtil.MEMENTO_SELECTED_CONTAINER;
 		}
 		if (fProjectButton.getSelection()) {
-			return "${project}"; //$NON-NLS-1$
+			return RefreshUtil.MEMENTO_SELECTED_PROJECT;
 		}
 		if (fWorkingSetButton.getSelection()) {
 			return getRefreshAttribute(fWorkingSet);
@@ -410,46 +382,7 @@
 	 * @throws CoreException if an exception occurs while refreshing resources
 	 */
 	public static void refreshResources(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
-		if (monitor == null) {
-			monitor = new NullProgressMonitor();
-		}
-		String scope = getRefreshScope(configuration);
-		IResource[] resources= null;
-		if (scope != null) {
-			resources = getRefreshResources(scope);
-		}
-		if (resources == null || resources.length == 0){
-			return;
-		}
-		int depth = IResource.DEPTH_ONE;
-		if (isRefreshRecursive(configuration))
-			depth = IResource.DEPTH_INFINITE;
-	
-		if (monitor.isCanceled()) {
-			return;
-		}
-	
-		monitor.beginTask(StringSubstitutionMessages.RefreshTab_7, 
-			resources.length);
-	
-		MultiStatus status = new MultiStatus(DebugUIPlugin.getUniqueIdentifier(), 0, StringSubstitutionMessages.RefreshTab_8, null); 
-		for (int i = 0; i < resources.length; i++) {
-			if (monitor.isCanceled())
-				break;
-			if (resources[i] != null && resources[i].isAccessible()) {
-				try {
-					resources[i].refreshLocal(depth, null);
-				} catch (CoreException e) {
-					status.merge(e.getStatus());
-				}
-			}
-			monitor.worked(1);
-		}
-	
-		monitor.done();
-		if (!status.isOK()) {
-			throw new CoreException(status);
-		}
+		RefreshUtil.refreshResources(configuration, monitor);
 	}
 
 	/**
@@ -460,76 +393,10 @@
 	 * @throws CoreException if unable to resolve a set of resources
 	 */
 	public static IResource[] getRefreshResources(String scope) throws CoreException {
-		if (scope.startsWith("${resource:")) { //$NON-NLS-1$
-			// This is an old format that is replaced with 'working_set'
-			String pathString = scope.substring(11, scope.length() - 1);
-			Path path = new Path(pathString);
-			IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
-			if (resource == null) {
-				throw new CoreException(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, MessageFormat.format(StringSubstitutionMessages.RefreshTab_43, new String[]{pathString}), null)); 
-			} 
-			return new IResource[]{resource};
-		} else if (scope.startsWith("${working_set:")) { //$NON-NLS-1$
-			IWorkingSet workingSet =  getWorkingSet(scope);
-			if (workingSet == null) {
-				throw new CoreException(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, StringSubstitutionMessages.RefreshTab_44, null));  
-			} 
-			IAdaptable[] elements = workingSet.getElements();
-			IResource[] resources = new IResource[elements.length];
-			for (int i = 0; i < elements.length; i++) {
-				IAdaptable adaptable = elements[i];
-				if (adaptable instanceof IResource) {
-					resources[i] = (IResource) adaptable;
-				} else {
-					resources[i] = (IResource) adaptable.getAdapter(IResource.class);
-				}
-			}
-			return resources;				
-		} else if(scope.equals("${workspace}")) { //$NON-NLS-1$
-			return new IResource[]{ResourcesPlugin.getWorkspace().getRoot()};
-		} else {
-			IResource resource = SelectedResourceManager.getDefault().getSelectedResource();
-			if (resource == null) {
-				// empty selection
-				return new IResource[]{};
-			}
-			if (scope.equals("${resource}")) { //$NON-NLS-1$
-				// resource = resource
-			} else if (scope.equals("${container}")) { //$NON-NLS-1$
-				resource = resource.getParent();
-			} else if (scope.equals("${project}")) { //$NON-NLS-1$
-				resource = resource.getProject();
-			}
-			return new IResource[]{resource};
-		}
+		return RefreshUtil.toResources(scope);
 	}
 	
 	/**
-	 * Restores a working set based on the XMLMemento represented within
-	 * the mementoString.
-	 * 
-	 * @param mementoString The string memento of the working set
-	 * @return the restored working set or <code>null</code> if problems occurred restoring the
-	 * working set.
-	 */
-	private static IWorkingSet restoreWorkingSet(String mementoString) {
-		if (NO_WORKING_SET.equals(mementoString)) {
-			return null;
-		}
-		StringReader reader= new StringReader(mementoString);
-		XMLMemento memento= null;
-		try {
-			memento = XMLMemento.createReadRoot(reader);
-		} catch (WorkbenchException e) {
-			DebugUIPlugin.log(e);
-			return null;
-		}
-
-		IWorkingSetManager workingSetManager= PlatformUI.getWorkbench().getWorkingSetManager();
-		return workingSetManager.createWorkingSet(memento);
-	}	
-	
-	/**
 	 * Returns the refresh scope attribute specified by the given launch configuration
 	 * or <code>null</code> if none.
 	 * 
@@ -561,29 +428,16 @@
 	 * @return an equivalent refresh attribute
 	 */
 	public static String getRefreshAttribute(IWorkingSet workingSet) {
-		String set = null;
 		if (workingSet == null || workingSet.getElements().length == 0) {
-			set = NO_WORKING_SET;
+			return RefreshUtil.toMemento(new IResource[0]);
 		} else {
-			XMLMemento workingSetMemento = XMLMemento.createWriteRoot(TAG_LAUNCH_CONFIGURATION_WORKING_SET);
-			workingSetMemento.putString(RefreshTab.TAG_FACTORY_ID, workingSet.getFactoryId());
-			workingSet.saveState(workingSetMemento);
-			StringWriter writer= new StringWriter();
-			try {
-				workingSetMemento.save(writer);
-			} catch (IOException e) {
-				DebugUIPlugin.log(e);
+			IAdaptable[] elements = workingSet.getElements();
+			IResource[] resources = new IResource[elements.length];
+			for (int i = 0; i < resources.length; i++) {
+				resources[i]= (IResource) elements[i].getAdapter(IResource.class);
 			}
-			set = writer.toString();
+			return RefreshUtil.toMemento(resources);
 		}
-		if (set != null) {
-			StringBuffer memento = new StringBuffer();
-			memento.append("${working_set:"); //$NON-NLS-1$
-			memento.append(set);
-			memento.append("}"); //$NON-NLS-1$
-			return memento.toString();
-		}
-		return null;
 	}
 	
 	/**
@@ -596,8 +450,14 @@
 	 */
 	public static IWorkingSet getWorkingSet(String refreshAttribute) {
 		if (refreshAttribute.startsWith("${working_set:")) { //$NON-NLS-1$
-			String memento = refreshAttribute.substring(14, refreshAttribute.length() - 1);
-			return  restoreWorkingSet(memento);
+			try {
+				IResource[] resources = RefreshUtil.toResources(refreshAttribute);
+				IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
+				IWorkingSet workingSet = workingSetManager.createWorkingSet(StringSubstitutionMessages.RefreshTab_1, resources);
+				return workingSet;
+			} catch (CoreException e) {
+				DebugUIPlugin.log(e);
+			}
 		}
 		return null;
 	}
@@ -615,4 +475,13 @@
 	public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) {
 		// do nothing on deactivation
 	}
+	
+	/**
+	 * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getId()
+	 * 
+	 * @since 3.5
+	 */
+	public String getId() {
+		return "org.eclipse.debug.ui.refreshTab"; //$NON-NLS-1$
+	}
 }
diff --git a/org.eclipse.ui.externaltools/META-INF/MANIFEST.MF b/org.eclipse.ui.externaltools/META-INF/MANIFEST.MF
index b7213c6..f645f57 100644
--- a/org.eclipse.ui.externaltools/META-INF/MANIFEST.MF
+++ b/org.eclipse.ui.externaltools/META-INF/MANIFEST.MF
@@ -19,6 +19,6 @@
  org.eclipse.debug.core;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.debug.ui;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.1.0,4.0.0)",
- org.eclipse.core.externaltools;bundle-version="[1.0.0,2.0.0)"
+ org.eclipse.core.externaltools;bundle-version="[0.0.9,1.0.0)"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.4