Bug 492182 - Add Terminate and Relaunch from Configurations, Relaunch
actions and Context based launch

Change-Id: Icef7f143a7d967c5d7126180a359fd4fcbe3422e
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java
index 0a7e13f..c91cc56 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/AbstractDebugActionDelegate.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -21,6 +21,7 @@
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.BusyIndicator;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
@@ -59,9 +60,14 @@
 	private boolean fInitialized = false;
 	
 	/**
-	 * It's crucial that delegate actions have a zero-argument constructor so that
-	 * they can be reflected into existence when referenced in an action set
-	 * in the plugin's plugin.xml file.
+	 * Whether this delegate was started with Shift pressed
+	 */
+	private boolean fIsShift = false;
+
+	/**
+	 * It's crucial that delegate actions have a zero-argument constructor so
+	 * that they can be reflected into existence when referenced in an action
+	 * set in the plugin's plugin.xml file.
 	 */
 	public AbstractDebugActionDelegate() {}
 	
@@ -83,7 +89,7 @@
 			// disable the action so it cannot be run again until an event or selection change
 			// updates the enablement
 			action.setEnabled(false);
-			runInForeground(selection);
+			runInForeground(selection, false);
 	    }
 	}
 	
@@ -91,7 +97,8 @@
 	 * Runs this action in the UI thread.
 	 * @param selection the current selection
 	 */
-	private void runInForeground(final IStructuredSelection selection) {
+	private void runInForeground(final IStructuredSelection selection, boolean isShift) {
+		fIsShift = isShift;
 	    final MultiStatus status= 
 			new MultiStatus(DebugUIPlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, getStatusMessage(), null); 	    
 		BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
@@ -320,12 +327,27 @@
 		return true;
 	}
 
+	/**
+	 * Returns if this action is started with Shift pressed
+	 * @return true if it is, false otherwise
+	 */
+	protected boolean isShift() {
+		return fIsShift;
+	}
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event)
 	 */
 	@Override
 	public void runWithEvent(IAction action, Event event) {
-		run(action);
+		if (action.isEnabled()) {
+			IStructuredSelection selection = getSelection();
+			// disable the action so it cannot be run again until an event or
+			// selection change
+			// updates the enablement
+			action.setEnabled(false);
+			runInForeground(selection, ((event.stateMask & SWT.SHIFT) > 0) ? true : false);
+		}
 	}
 
 	/* (non-Javadoc)
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchConfigurationAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchConfigurationAction.java
index e318c0b..e554b3e 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchConfigurationAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchConfigurationAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2013 IBM Corporation and others.
+ * Copyright (c) 2006, 2016 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
@@ -60,7 +60,7 @@
 	 */
 	@Override
 	public void run() {
-		DebugUITools.launch(fConfig, fMode);
+		runInternal(false);
 	}
 	
 	/* (non-Javadoc)
@@ -75,13 +75,17 @@
 					DebugUITools.openLaunchConfigurationDialogOnGroup(DebugUIPlugin.getShell(), new StructuredSelection(fConfig), group.getIdentifier());
 				}
 				else {
-					run();
+					runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
 				}
 			}
 			catch(CoreException ce) {}
 		}
 		else {
-			run();
+			runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
 		}
 	}
+
+	private void runInternal(boolean isShift) {
+		DebugUITools.launch(fConfig, fMode, isShift);
+	}
 }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java
index ff29633..c0c3d1c 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/LaunchShortcutAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -45,6 +45,7 @@
 	private String fMode;
 	private LaunchShortcutExtension fShortcut; 
 
+
 	/**
 	 * Constructor
 	 * @param groupid the id of the launch group
@@ -65,12 +66,20 @@
 	 */
 	@Override
 	public void run() {
+		runInternal(false);
+	}
+
+	private void runInternal(boolean isShift) {
 		IStructuredSelection ss = SelectedResourceManager.getDefault().getCurrentSelection();
 		Object o = ss.getFirstElement();
+		// store if Shift was pressed to toggle terminate before launch
+		// preference
 		if(o instanceof IEditorPart) {
+			DebugUITools.storeLaunchToggleTerminate(o, isShift);
 			fShortcut.launch((IEditorPart) o, fMode);
 		}
 		else {
+			DebugUITools.storeLaunchToggleTerminate(ss, isShift);
 			fShortcut.launch(ss, fMode);
 		}
 	}
@@ -120,7 +129,7 @@
 			}
 		}
 		else {
-			run();
+			runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
 		}
 	}
 	
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchActionDelegate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchActionDelegate.java
index 3b0f1a0..49ea108 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchActionDelegate.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchActionDelegate.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -30,19 +30,31 @@
 	 */
 	@Override
 	protected void doAction(Object object) {
-		ILaunch launch= DebugUIPlugin.getLaunch(object);
-        if (launch != null) {
-            relaunch(launch.getLaunchConfiguration(), launch.getLaunchMode());
-        }
+		ILaunch launch = DebugUIPlugin.getLaunch(object);
+		if (launch != null) {
+			relaunch(launch.getLaunchConfiguration(), launch.getLaunchMode(), isShift());
+		}
 	}
-	
+
 	/**
 	 * Re-launches the given configuration in the specified mode.
+	 * 
 	 */
 	public static void relaunch(ILaunchConfiguration config, String mode) {
-		DebugUITools.launch(config, mode);		
+		DebugUITools.launch(config, mode);
 	}
-	
+
+	/**
+	 * Re-launches the given configuration in the specified mode after
+	 * terminating the previous if Preferred.
+	 * 
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 */
+	public static void relaunch(ILaunchConfiguration config, String mode, boolean isShift) {
+		DebugUITools.launch(config, mode, isShift);
+	}
+
 	/**
 	 * @see AbstractDebugActionDelegate#isEnabledFor(Object)
 	 */
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java
index fe6b175..70e1bb4 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/contextlaunching/ContextRunner.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2013 IBM Corporation and others.
+ * Copyright (c) 2007, 2016 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
@@ -72,28 +72,59 @@
 	private LaunchingResourceManager fLRM = DebugUIPlugin.getDefault().getLaunchingResourceManager();
 	
 	/**
-	 * Performs the context launching given the object context and the mode to launch in.
+	 * Performs the context launching given the object context and the mode to
+	 * launch in.
+	 * 
 	 * @param group the launch group to launch using
+	 * @deprecated use launch(ILaunchGroup, boolean)
 	 */
+	@Deprecated
 	public void launch(ILaunchGroup group) {
-		IStructuredSelection selection = SelectedResourceManager.getDefault().getCurrentSelection();
-		IResource resource = SelectedResourceManager.getDefault().getSelectedResource();
-		selectAndLaunch(resource, group, selection);
+		launch(group, false);
 	}
 	
-	
+	/**
+	 * Performs the context launching given the object context and the mode to
+	 * launch in.
+	 * 
+	 * @param group the launch group to launch using
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 */
+	public void launch(ILaunchGroup group, boolean isShift) {
+		IStructuredSelection selection = SelectedResourceManager.getDefault().getCurrentSelection();
+		IResource resource = SelectedResourceManager.getDefault().getSelectedResource();
+		selectAndLaunch(resource, group, selection, isShift);
+	}
 	
 	/**
 	 * This method launches the last configuration that was launched, if any.
+	 * 
 	 * @param group the launch group to launch with
-	 * @return true if there was a last launch and it was launched, false otherwise
+	 * @return true if there was a last launch and it was launched, false
+	 *         otherwise
+	 * @deprecated use launchLast(ILaunchGroup, boolean)
 	 */
+	@Deprecated
 	protected boolean launchLast(ILaunchGroup group) {
+		return launchLast(group, false);
+	}
+
+	/**
+	 * This method launches the last configuration that was launched, if any.
+	 * 
+	 * @param group the launch group to launch with
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 * @return true if there was a last launch and it was launched, false
+	 *         otherwise
+	 */
+	protected boolean launchLast(ILaunchGroup group, boolean isShift) {
 		ILaunchConfiguration config = null;
 		if(group != null) {
 			config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
 			if(config != null) {
-				launch(config, group.getMode());
+				launch(config, group.getMode(), isShift);
 				return true;
 			}
 		}
@@ -101,14 +132,31 @@
 	}
 	
 	/**
-	 * Prompts the user to select a way of launching the current resource, where a 'way'
-	 * is defined as a launch shortcut.
+	 * Prompts the user to select a way of launching the current resource, where
+	 * a 'way' is defined as a launch shortcut.
 	 * 
 	 * @param resource the resource context
 	 * @param group the launch group to launch with
 	 * @param selection the current selection
+	 * @deprecated use selectAndLaunch(IResource, ILaunchGroup,
+	 *             IStructuredSelection, boolean)
 	 */
+	@Deprecated
 	protected void selectAndLaunch(IResource resource, ILaunchGroup group, IStructuredSelection selection) {
+		selectAndLaunch(resource, group, selection, false);
+	}
+
+	/**
+	 * Prompts the user to select a way of launching the current resource, where
+	 * a 'way' is defined as a launch shortcut.
+	 * 
+	 * @param resource the resource context
+	 * @param group the launch group to launch with
+	 * @param selection the current selection
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 */
+	protected void selectAndLaunch(IResource resource, ILaunchGroup group, IStructuredSelection selection, boolean isShift) {
 		if(group != null) {			
 			LaunchConfigurationManager lcm = DebugUIPlugin.getDefault().getLaunchConfigurationManager();
 			String mode = group.getMode();
@@ -122,33 +170,33 @@
 		//see if the context is a shared configuration
 			ILaunchConfiguration config = lcm.isSharedConfig(resource);
 			if(config != null) {
-				launch(config, mode);
+				launch(config, mode, isShift);
 				return;
 			}
 		//get the configurations from the resource and participants	
 			List<ILaunchConfiguration> configs = fLRM.getParticipatingLaunchConfigurations(selection, resource, shortcuts, mode);
 			int csize = configs.size();
 			if(csize == 1) {
-				launch(configs.get(0), mode);
+				launch(configs.get(0), mode, isShift);
 			}
 			else if(csize < 1) {
 				int esize = shortcuts.size();
 				if(esize == 1) {
-					launchShortcut(selection, shortcuts.get(0), mode);
+					launchShortcut(selection, shortcuts.get(0), mode, isShift);
 				}
 				else if(esize > 1) {
-					showShortcutSelectionDialog(resource, shortcuts, mode, selection);
+					showShortcutSelectionDialog(resource, shortcuts, mode, selection, isShift);
 				}
 				else if(esize < 1) {
 					if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE)) {
-						if(!launchLast(group)) {
+						if (!launchLast(group, isShift)) {
 							MessageDialog.openInformation(DebugUIPlugin.getShell(), ContextMessages.ContextRunner_0, ContextMessages.ContextRunner_7);
 						}
 					} else {
 						if(resource != null) {
 							IProject project = resource.getProject();
 							if(project != null && !project.equals(resource)) {
-								selectAndLaunch(project, group, new StructuredSelection(project));
+								selectAndLaunch(project, group, new StructuredSelection(project), isShift);
 							}
 							else {
 								String msg = ContextMessages.ContextRunner_7;
@@ -159,7 +207,7 @@
 							}
 						}
 						else {
-							if (!launchLast(group)) {
+							if (!launchLast(group, isShift)) {
 								MessageDialog.openInformation(DebugUIPlugin.getShell(), ContextMessages.ContextRunner_0, ContextMessages.ContextRunner_7);
 							}
 						}
@@ -169,9 +217,9 @@
 			else if(csize > 1){
 				config = lcm.getMRUConfiguration(configs, group, resource);
 				if(config != null) {
-					launch(config, mode);
+					launch(config, mode, isShift);
 				} else {
-					showConfigurationSelectionDialog(configs, mode);
+					showConfigurationSelectionDialog(configs, mode, isShift);
 				}
 			}
 		}
@@ -182,28 +230,36 @@
 	 * 
 	 * @param configuration configuration to launch
 	 * @param mode launch mode identifier
+	 * @param isShift is Shift pressed
 	 */
-	private void launch(ILaunchConfiguration configuration, String mode) {
+	private void launch(ILaunchConfiguration configuration, String mode, boolean isShift) {
 		if (validateMode(configuration, mode)) {
-			DebugUITools.launch(configuration, mode);
+			DebugUITools.launch(configuration, mode, isShift);
 		}
 	}
 	
 	/**
-	 * Delegate method that calls the appropriate launch method on a <code>LaunchShortcutExtension</code> given 
-	 * the current resource and selection context 
+	 * Delegate method that calls the appropriate launch method on a
+	 * <code>LaunchShortcutExtension</code> given the current resource and
+	 * selection context
+	 * 
 	 * @param selection the current selection
 	 * @param shortcut the shortcut that wants to launch
 	 * @param mode the mode to launch in
+	 * @param isShift is Shift pressed
 	 * 
 	 * @since 3.4
 	 */
-	private void launchShortcut(IStructuredSelection selection, LaunchShortcutExtension shortcut, String mode) {
+	private void launchShortcut(IStructuredSelection selection, LaunchShortcutExtension shortcut, String mode, boolean isShift) {
 		Object o = selection.getFirstElement();
+		// store if Shift was pressed to toggle terminate before launch
+		// preference
 		if(o instanceof IEditorPart) {
+			DebugUITools.storeLaunchToggleTerminate(o, isShift);
 			shortcut.launch((IEditorPart) o, mode);
 		}
 		else {
+			DebugUITools.storeLaunchToggleTerminate(selection, isShift);
 			shortcut.launch(selection, mode);
 		}
 	}
@@ -243,17 +299,34 @@
 	}
 	
 	/**
-	 * Presents the user with a dialog to pick the launch configuration to launch
-	 * and launches that configuration.
+	 * Presents the user with a dialog to pick the launch configuration to
+	 * launch and launches that configuration.
 	 * 
 	 * @param configurations the listing of applicable configurations to present
 	 * @param mode the mode
+	 * @deprecated use
+	 *             showConfigurationSelectionDialog(List<ILaunchConfiguration>,
+	 *             String, boolean)
 	 */
+	@Deprecated
 	protected void showConfigurationSelectionDialog(List<ILaunchConfiguration> configurations, String mode) {
+		showConfigurationSelectionDialog(configurations, mode, false);
+	}
+
+	/**
+	 * Presents the user with a dialog to pick the launch configuration to
+	 * launch and launches that configuration.
+	 * 
+	 * @param configurations the listing of applicable configurations to present
+	 * @param mode the mode
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 */
+	protected void showConfigurationSelectionDialog(List<ILaunchConfiguration> configurations, String mode, boolean isShift) {
 		LaunchConfigurationSelectionDialog lsd = new LaunchConfigurationSelectionDialog(DebugUIPlugin.getShell(), configurations);
 		if(lsd.open() == IDialogConstants.OK_ID) {
 			ILaunchConfiguration config = (ILaunchConfiguration) lsd.getResult()[0];
-			launch(config, mode);
+			launch(config, mode, isShift);
 		}
 	}
 	
@@ -265,15 +338,34 @@
 	 * @param shortcuts the list of applicable shortcuts
 	 * @param mode the mode
 	 * @param selection the current selection
+	 * @deprecated use showShortcutSelectionDialog(IResource,
+	 *             List<LaunchShortcutExtension>, String,IStructuredSelection,
+	 *             boolean)
 	 */
+	@Deprecated
 	protected void showShortcutSelectionDialog(IResource resource, List<LaunchShortcutExtension> shortcuts, String mode, IStructuredSelection selection) {
+		showShortcutSelectionDialog(resource, shortcuts, mode, selection, false);
+	}
+
+	/**
+	 * Presents a selection dialog to the user to pick a launch shortcut and
+	 * launch using that shortcut.
+	 * 
+	 * @param resource the resource context
+	 * @param shortcuts the list of applicable shortcuts
+	 * @param mode the mode
+	 * @param selection the current selection
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 */
+	protected void showShortcutSelectionDialog(IResource resource, List<LaunchShortcutExtension> shortcuts, String mode, IStructuredSelection selection, boolean isShift) {
 		LaunchShortcutSelectionDialog dialog = new LaunchShortcutSelectionDialog(shortcuts, resource, mode);
 		if (dialog.open() == Window.OK) {
 			Object[] result = dialog.getResult();
 			if(result.length > 0) {
 				LaunchShortcutExtension method = (LaunchShortcutExtension) result[0];
 				if(method != null) {
-					launchShortcut(selection, method, mode);
+					launchShortcut(selection, method, mode, isShift);
 				}
 			}
 		}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java
index e897993..75da0d6 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2013 IBM Corporation and others.
+ *  Copyright (c) 2000, 2016 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
@@ -68,6 +68,8 @@
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.custom.ViewForm;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
@@ -78,6 +80,8 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.ToolBar;
@@ -161,6 +165,8 @@
 	 */
 	private int fOpenMode = LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED;
 	
+	private boolean fIsShift = false;
+
 	/**
 	 * dialog settings
 	 */
@@ -420,7 +426,20 @@
 		return composite;
 	}
 
-	
+	/**
+	 * 
+	 * @param buttonId
+	 */
+	protected void launchButtonPressed(int buttonId) {
+		if (buttonId == ID_LAUNCH_BUTTON) {
+			handleLaunchPressed();
+		} else if (buttonId == ID_CLOSE_BUTTON) {
+			handleClosePressed();
+		} else {
+			super.buttonPressed(buttonId);
+		}
+	}
+
 	
 	/**
 	 * A launch configuration dialog overrides this method
@@ -434,6 +453,22 @@
 	protected void createButtonsForButtonBar(Composite parent) {
 		Button button = createButton(parent, ID_LAUNCH_BUTTON, getLaunchButtonText(), true);
         button.setEnabled(false);
+		Listener[] listeners = button.getListeners(SWT.Selection);
+		for (Listener listener : listeners) {
+			button.removeListener(SWT.Selection, listener);
+		}
+		listeners = button.getListeners(SWT.DefaultSelection);
+		for (Listener listener : listeners) {
+			button.removeListener(SWT.DefaultSelection, listener);
+		}
+
+		button.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				setShift(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
+				handleLaunchPressed();
+			}
+		});
 		createButton(parent, ID_CLOSE_BUTTON, LaunchConfigurationsMessages.LaunchConfigurationDialog_Close_1, false);
 	}
 	
@@ -490,6 +525,9 @@
 		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
 	}
     
+	protected void setShift(boolean isShift) {
+		fIsShift = isShift;
+	}
 	/**
 	 * Creates the launch configuration selection area of the dialog.
 	 * This area displays a tree of launch configurations that the user
@@ -532,10 +570,20 @@
 		fDoubleClickAction = new Action() {
 			@Override
 			public void run() {
+				runInternal(false);
+			}
+
+			@Override
+			public void runWithEvent(Event event) {
+				runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
+			}
+
+			void runInternal(boolean isShift) {
 				IStructuredSelection selection = (IStructuredSelection)fLaunchConfigurationView.getViewer().getSelection();
 				Object target = selection.getFirstElement();
 				if (target instanceof ILaunchConfiguration) {
 					if (fTabViewer.canLaunch() & fTabViewer.canLaunchWithModes() & !fTabViewer.hasDuplicateDelegates()) {
+						setShift(isShift);
 						handleLaunchPressed();
 					}
 				} else {
@@ -974,8 +1022,8 @@
   	}
  	
 	/**
-	 * Notification the 'launch' button has been pressed.
-	 * Save and launch.
+	 * Notification the 'launch' button has been pressed. Save and launch.
+	 * 
 	 */
 	protected void handleLaunchPressed() {
 		ILaunchConfiguration config = fTabViewer.getOriginal();
@@ -984,8 +1032,9 @@
 		}
 		if(config != null) {
 			close();
-			DebugUITools.launch(config, getMode());
+			DebugUITools.launch(config, getMode(), fIsShift);
 		}
+		setShift(false);
 	}
 
 	/**
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchShortcutExtension.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchShortcutExtension.java
index ab8e23e..c342dcb 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchShortcutExtension.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchShortcutExtension.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -429,9 +429,10 @@
 		ILaunchShortcut shortcut = getDelegate();
 		if (shortcut != null) {
 			shortcut.launch(selection, mode);
-		}		
+		}
 	}
-	
+
+
 	/**
 	 * Returns the set of modes this shortcut supports.
 	 * 
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties
index 5d7a2de..a50e596 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties
@@ -84,7 +84,7 @@
 LaunchingPreferencePage_40=Launch Operation
 LaunchingPreferencePage_41=La&unch the previously launched application
 LaunchingPreferencePage_confirm_0=Prompt for confirmation when removin&g a configuration from the launch history
-LaunchingPreferencePage_42=Termin&ate and Relaunch while launching from history (Press 'Shift' to toggle during launch)
+LaunchingPreferencePage_42=Termin&ate and Relaunch while launching (Press 'Shift' to toggle during launch from menu and toolbar)
 
 ProcessPropertyPage_Command_Line__1=Co&mmand Line:
 ProcessPropertyPage_0=Run-&at time:
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
index c6c8573..df2c46e 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -11,6 +11,8 @@
 package org.eclipse.debug.ui;
 
 
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Set;
 
 import org.eclipse.core.commands.ExecutionEvent;
@@ -19,10 +21,8 @@
 import org.eclipse.core.commands.operations.IUndoContext;
 import org.eclipse.core.commands.operations.IUndoableOperation;
 import org.eclipse.core.commands.operations.ObjectUndoContext;
-
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IResource;
-
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IConfigurationElement;
@@ -31,12 +31,14 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
-
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationType;
 import org.eclipse.debug.core.ILaunchDelegate;
+import org.eclipse.debug.core.ILaunchManager;
 import org.eclipse.debug.core.model.IBreakpoint;
 import org.eclipse.debug.core.model.IDebugElement;
 import org.eclipse.debug.core.model.IDebugTarget;
@@ -47,6 +49,7 @@
 import org.eclipse.debug.internal.ui.DebugUIPlugin;
 import org.eclipse.debug.internal.ui.DefaultLabelProvider;
 import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
+import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
 import org.eclipse.debug.internal.ui.LazyModelPresentation;
 import org.eclipse.debug.internal.ui.actions.ActionMessages;
 import org.eclipse.debug.internal.ui.actions.ToggleBreakpointsTargetManager;
@@ -60,7 +63,6 @@
 import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupFacility;
 import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupUIUtils;
 import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
-
 import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetManager;
 import org.eclipse.debug.ui.contexts.IDebugContextListener;
 import org.eclipse.debug.ui.contexts.IDebugContextManager;
@@ -68,18 +70,20 @@
 import org.eclipse.debug.ui.memory.IMemoryRenderingManager;
 import org.eclipse.debug.ui.sourcelookup.ISourceContainerBrowser;
 import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
-
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
 import org.eclipse.jface.window.Window;
-
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.custom.BusyIndicator;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Shell;
-
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IViewSite;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
@@ -754,19 +758,157 @@
 	}	
 	
 	/**
-	 * Saves and builds the workspace according to current preference settings, and
-	 * launches the given launch configuration in the specified mode.
+	 * Saves and builds the workspace according to current preference settings,
+	 * and launches the given launch configuration in the specified mode. It
+	 * terminates the current launch for the same configuration if it was
+	 * specified via Preferences or toggled by Shift.
 	 * <p>
 	 * This method must be called in the UI thread.
 	 * </p>
+	 * 
 	 * @param configuration the configuration to launch
 	 * @param mode launch mode - run or debug
 	 * @since 2.1
 	 */
 	public static void launch(final ILaunchConfiguration configuration, final String mode) {
-		boolean launchInBackground= true;
+		launch(configuration, mode, DebugUITools.findTogglelaunchForConfig(configuration));
+	}
+
+	private static HashMap<Object, Boolean> fgLaunchToggleTerminateMap = new HashMap<>();
+
+	/**
+	 * Stores the toggle data for launch in a Map to be used while launching to
+	 * decide if previous launch for same configuration can be terminated.
+	 * 
+	 * @param data the editor or selected tree node
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 * @since 3.12
+	 */
+	public static void storeLaunchToggleTerminate(Object data, Boolean isShift) {
+		synchronized (fgLaunchToggleTerminateMap) {
+			fgLaunchToggleTerminateMap.put(data, isShift);
+		}
+	}
+
+	/**
+	 * @since 3.12
+	 */
+	private static boolean getAndRemoveLaunchToggleTerminate(Object data) {
+
+		Boolean isShift;
+		synchronized (fgLaunchToggleTerminateMap) {
+			isShift = fgLaunchToggleTerminateMap.get(data);
+		}
+		if (isShift != null) {
+			synchronized (fgLaunchToggleTerminateMap) {
+				fgLaunchToggleTerminateMap.remove(data);
+			}
+			return isShift.booleanValue();
+		}
+		return Boolean.FALSE;
+	}
+
+	/**
+	 * @since 3.12
+	 */
+	private static boolean findTogglelaunchForConfig(ILaunchConfiguration configuration) {
+		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
+		ILaunch[] launches = launchManager.getLaunches();
+		for (ILaunch iLaunch : launches) {
+			if (configuration.contentsEqual(iLaunch.getLaunchConfiguration())) {
+				try {
+					IResource[] configResource = iLaunch.getLaunchConfiguration().getMappedResources();
+					if (configResource != null && configResource.length == 1) {
+						for (Iterator<Object> iter = fgLaunchToggleTerminateMap.keySet().iterator(); iter.hasNext();) {
+							Object key = iter.next();
+							if (key instanceof IEditorPart) {
+								IEditorInput input = ((IEditorPart) key).getEditorInput();
+								if (input.getAdapter(IResource.class).equals(configResource[0])) {
+									return getAndRemoveLaunchToggleTerminate(key);
+								}
+							} else if (key instanceof TreeSelection) {
+								TreeSelection selection = (TreeSelection) key;
+								TreePath[] treePath = selection.getPaths();
+								if (treePath != null && treePath.length == 1) {
+									Object lastSegmentObj = treePath[0].getLastSegment();
+									IResource selectedResource = ((IAdaptable) lastSegmentObj).getAdapter(IResource.class);
+									if (selectedResource!= null && selectedResource.equals(configResource[0])) {
+										return getAndRemoveLaunchToggleTerminate(key);
+									}
+								}
+							}
+						}
+					}
+
+				} catch (CoreException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return false;
+
+	}
+	
+	/**
+	 * Saves and builds the workspace according to current preference settings,
+	 * and launches the given launch configuration in the specified mode.
+	 * <p>
+	 * This method must be called in the UI thread.
+	 * </p>
+	 * 
+	 * @param configuration the configuration to launch
+	 * @param mode launch mode - run or debug
+	 * @since 3.12
+	 */
+	public static void reLaunch(final ILaunchConfiguration configuration, final String mode) {
+		boolean launchInBackground = true;
 		try {
-			launchInBackground= configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
+			launchInBackground = configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
+		} catch (CoreException e) {
+			DebugUIPlugin.log(e);
+		}
+		if (launchInBackground) {
+			DebugUIPlugin.launchInBackground(configuration, mode);
+		} else {
+			DebugUIPlugin.launchInForeground(configuration, mode);
+		}
+
+	}
+
+
+	/**
+	 * Saves and builds the workspace according to current preference settings,
+	 * and launches the given launch configuration in the specified mode. It
+	 * terminates the current launch for the same configuration if it was
+	 * specified via Preferences or toggled by Shift
+	 * <p>
+	 * This method must be called in the UI thread.
+	 * </p>
+	 * 
+	 * @param configuration the configuration to launch
+	 * @param mode launch mode - run or debug
+	 * @param isShift is Shift pressed (use <code>false</code> if no support for
+	 *            Shift)
+	 * @since 3.12
+	 */
+	public static void launch(final ILaunchConfiguration configuration, final String mode, boolean isShift) {
+		if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_TERMINATE_AND_RELAUNCH_LAUNCH_ACTION) != isShift) {
+			ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
+			ILaunch[] launches = launchManager.getLaunches();
+			for (ILaunch iLaunch : launches) {
+				if (configuration.contentsEqual(iLaunch.getLaunchConfiguration())) {
+					try {
+						iLaunch.terminate();
+					} catch (DebugException e) {
+						DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), NLS.bind(ActionMessages.TerminateAndLaunchFailure, iLaunch.getLaunchConfiguration().getName()), e));
+					}
+				}
+			}
+		}
+		boolean launchInBackground = true;
+		try {
+			launchInBackground = configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
 		} catch (CoreException e) {
 			DebugUIPlugin.log(e);
 		}
@@ -776,7 +918,6 @@
 			DebugUIPlugin.launchInForeground(configuration, mode);
 		}
 	}
-	
 
 	
 	/**
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchHistoryAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchHistoryAction.java
index 4ec9851..65590c8 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchHistoryAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchHistoryAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -417,6 +417,13 @@
 					true);
 			return;
 		}
+		runInternal(action, ((event.stateMask & SWT.SHIFT) > 0) ? true : false);
+	}
+
+	/**
+	 * @since 3.12
+	 */
+	protected void runInternal(IAction action, boolean isShift) {
 		run(action);
 	}
 
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchToolbarAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchToolbarAction.java
index aed6e70..685422b 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchToolbarAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/AbstractLaunchToolbarAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -77,17 +77,22 @@
 	 */
 	@Override
 	public void run(IAction action) {
+		runInternal(action, false);
+	}
+
+	@Override
+	protected void runInternal(IAction action, boolean isShift) {
 		//always ignore external tools during context launching
 		if(LaunchingResourceManager.isContextLaunchEnabled(getLaunchGroupIdentifier())) {
-			ContextRunner.getDefault().launch(DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(getLaunchGroupIdentifier()));
+			ContextRunner.getDefault().launch(DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(getLaunchGroupIdentifier()), isShift);
 		}
 		else {
 			ILaunchConfiguration configuration = getLastLaunch();
 			if (configuration == null) {
 				DebugUITools.openLaunchConfigurationDialogOnGroup(DebugUIPlugin.getShell(), new StructuredSelection(), getLaunchGroupIdentifier());
 			} else {
-				DebugUITools.launch(configuration, getMode());
+				DebugUITools.launch(configuration, getMode(), isShift);
 			}
 		}
-	}	
+	}
 }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAction.java
index 8b85002..5277097 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/LaunchAction.java
@@ -15,14 +15,8 @@
 import java.util.Set;
 
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationType;
-import org.eclipse.debug.core.ILaunchManager;
 import org.eclipse.debug.internal.ui.DebugUIPlugin;
 import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
@@ -35,7 +29,6 @@
 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.ui.PlatformUI;
@@ -84,24 +77,13 @@
 	 */
 	@Override
 	public void run() {
-		DebugUITools.launch(fConfiguration, fMode);
+		runInternal(false);
 	}
 
-	private void terminateIfPreferred(boolean isShift) {
-		if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_TERMINATE_AND_RELAUNCH_LAUNCH_ACTION) != isShift) {
-			ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
-			ILaunch[] launches = launchManager.getLaunches();
-			for (ILaunch iLaunch : launches) {
-				if (fConfiguration.contentsEqual(iLaunch.getLaunchConfiguration())) {
-					try {
-						iLaunch.terminate();
-					} catch (DebugException e) {
-						DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), NLS.bind(ActionMessages.TerminateAndLaunchFailure, iLaunch.getLaunchConfiguration().getName()), e));
-					}
-				}
-			}
-		}
+	private void runInternal(boolean isShift) {
+		DebugUITools.launch(fConfiguration, fMode, isShift);
 	}
+
 	/**
 	 * If the user has control-clicked the launch history item, open the launch
 	 * configuration dialog on the launch configuration, rather than running it.
@@ -140,12 +122,11 @@
 				DebugUITools.openLaunchConfigurationDialogOnGroup(DebugUIPlugin.getShell(), new StructuredSelection(fConfiguration), group.getIdentifier());
 			}
 			else {
-				run();
+				runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
 			}
 		} 
 		else {
-			terminateIfPreferred(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
-			run();
+			runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
 		}
 	}
 	
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RelaunchLastAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RelaunchLastAction.java
index 26fe989..3de0d72 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RelaunchLastAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/actions/RelaunchLastAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2000, 2013 IBM Corporation and others.

+ * Copyright (c) 2000, 2016 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

@@ -35,7 +35,10 @@
 import org.eclipse.jface.action.IAction;

 import org.eclipse.jface.dialogs.MessageDialog;

 import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.widgets.Event;

 import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.IActionDelegate2;

 import org.eclipse.ui.IWorkbenchWindow;

 import org.eclipse.ui.IWorkbenchWindowActionDelegate;

 import org.eclipse.ui.PlatformUI;

@@ -53,7 +56,7 @@
  * @see ProfileLastAction

  * @since 3.8

  */

-public abstract class RelaunchLastAction implements IWorkbenchWindowActionDelegate {

+public abstract class RelaunchLastAction implements IWorkbenchWindowActionDelegate, IActionDelegate2 {

 

 	private class Listener implements IPreferenceChangeListener {

 		/* (non-Javadoc)

@@ -94,21 +97,57 @@
 		}

 	}

 

+	/*

+	 * (non-Javadoc)

+	 * @see

+	 * org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction)

+	 */

+	/**

+	 * @since 3.12

+	 */

+	@Override

+	public void init(IAction action) {

+		initialize(action);

+		IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(DebugUIPlugin.getUniqueIdentifier());

+		if (prefs != null) {

+			prefs.addPreferenceChangeListener(fListener);

+		}

+	}

+

 	/* (non-Javadoc)

 	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)

 	 */

 	@Override

-	public void run(IAction action){		

+	public void run(IAction action) {

+		runInternal(false);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see

+	 * org.eclipse.ui.IActionDelegate2#runwithEvent(org.eclipse.jface.action.

+	 * IAction, org.eclipse.swt.widgets.Event)

+	 */

+

+	/**

+	 * @since 3.12

+	 */

+	@Override

+	public void runWithEvent(IAction action, Event event) {

+		runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);

+	}

+

+	private void runInternal(boolean isShift) {

 		if(LaunchingResourceManager.isContextLaunchEnabled()) {

 			ILaunchGroup group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(getLaunchGroupId());

-			ContextRunner.getDefault().launch(group);

+			ContextRunner.getDefault().launch(group, isShift);

 			return;

 		}

 		try {

 			final ILaunchConfiguration configuration = getLastLaunch();

 			if (configuration != null) {

 				if (configuration.supportsMode(getMode())) {

-					DebugUITools.launch(configuration, getMode());

+					DebugUITools.launch(configuration, getMode(), isShift);

 				} else {

 					String configName = configuration.getName();

 					String title = ActionMessages.RelaunchLastAction_Cannot_relaunch_1; 

@@ -124,7 +163,7 @@
 			DebugUIPlugin.errorDialog(getShell(), ActionMessages.RelaunchLastAction_Error_relaunching_3, ActionMessages.RelaunchLastAction_Error_encountered_attempting_to_relaunch_4, ce); // 

 		}

 	}

-	

+

 	/**

 	 * Open the launch configuration dialog, passing in the current workbench selection.

 	 */