Bug 525253 - Bug 522554 - [9] Give an option for user to copy
--add-reads etc. classpath attributes from buildpath while launching

Change-Id: I4f152b24419e8d85348175a572794109f595b422
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java
index 35629ff..bb6fa4c 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java
@@ -34,9 +34,9 @@
 import org.eclipse.jdt.internal.debug.ui.actions.AddProjectAction;
 import org.eclipse.jdt.internal.debug.ui.actions.AddVariableAction;
 import org.eclipse.jdt.internal.debug.ui.actions.AttachSourceAction;
-import org.eclipse.jdt.internal.debug.ui.actions.EditClasspathEntryAction;
 import org.eclipse.jdt.internal.debug.ui.actions.MoveDownAction;
 import org.eclipse.jdt.internal.debug.ui.actions.MoveUpAction;
+import org.eclipse.jdt.internal.debug.ui.actions.OverrideDependenciesAction;
 import org.eclipse.jdt.internal.debug.ui.actions.RemoveAction;
 import org.eclipse.jdt.internal.debug.ui.actions.RestoreDefaultEntriesAction;
 import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction;
@@ -172,12 +172,14 @@
 		IAction[] adv = advancedActions.toArray(new IAction[advancedActions.size()]);
 		createButton(pathButtonComp, new AddAdvancedAction(fClasspathViewer, adv));
 
-		action = new EditClasspathEntryAction(fClasspathViewer, getLaunchConfiguration());
+		action = new OverrideDependenciesAction(fClasspathViewer, this);
 		createButton(pathButtonComp, action);
+		action.setEnabled(true);
 
 		action= new RestoreDefaultEntriesAction(fClasspathViewer, this);
 		createButton(pathButtonComp, action);
 		action.setEnabled(true);
+
 	}
 
 	/**
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java
index 7b0903c..abe0d47 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java
@@ -159,6 +159,10 @@
 
 	public static String TracepointToggleAction_Unavailable;
 
+	public static String Override_Dependencies_title;
+	public static String Override_Dependencies_button;
+	public static String Override_Dependencies_button1;
+
 	static {
 		// load message values from bundle file
 		NLS.initializeMessages(BUNDLE_NAME, ActionMessages.class);
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
index d67533c..7bc3e9a 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
@@ -139,4 +139,7 @@
 OpenTypeAction_2=Unable to display the selected type.
 EditClasspathEntryAction_0=Ed&it...
 ProjectSelectionDialog_0=Choose &project(s) to add:
-TracepointToggleAction_Unavailable=The operation is unavailable on the current selection.
\ No newline at end of file
+TracepointToggleAction_Unavailable=The operation is unavailable on the current selection.
+Override_Dependencies_title=Override Dependencies
+Override_Dependencies_button=Override
+Override_Dependencies_button1=&Override Dependencies
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OverrideDependenciesAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OverrideDependenciesAction.java
new file mode 100644
index 0000000..6924ef9
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OverrideDependenciesAction.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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.jdt.internal.debug.ui.actions;
+
+
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
+import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.actions.SelectionListenerAction;
+
+/**
+ * Overrides the dependencies specified in the Java Build path.
+ */
+public class OverrideDependenciesAction extends RuntimeClasspathAction {
+
+	private JavaClasspathTab fTab;
+
+	/**
+	 * Constructor
+	 * @param viewer the associated classpath viewer
+	 * @param tab the tab the viewer resides in
+	 */
+	public OverrideDependenciesAction(IClasspathViewer viewer, JavaClasspathTab tab) {
+		super(ActionMessages.Override_Dependencies_button1, viewer);
+		fTab = tab;
+	}
+
+	/**
+	 * View and override dependencies.
+	 *
+	 * @see org.eclipse.jface.action.Action#run()
+	 */
+	@Override
+	public void run() {
+		OverrideDependenciesDialog dialog = new OverrideDependenciesDialog(getShell(), ActionMessages.Override_Dependencies_title, null, null, 0, new String[] {
+				ActionMessages.Override_Dependencies_button, IDialogConstants.CANCEL_LABEL }, 0, fTab.getLaunchConfiguration());
+		int returnValue = dialog.open();
+		if (returnValue == 0) {
+			getViewer().notifyChanged();
+		}
+	}
+
+	/**
+	 * @see SelectionListenerAction#updateSelection(IStructuredSelection)
+	 */
+	@Override
+	protected boolean updateSelection(IStructuredSelection selection) {
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OverrideDependenciesDialog.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OverrideDependenciesDialog.java
new file mode 100644
index 0000000..5e9e94a
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OverrideDependenciesDialog.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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.jdt.internal.debug.ui.actions;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Allows the user to specify if they want to delete the working set, all the breakpoints in the working
+ * set or both
+ * @since 3.2
+ */
+public class OverrideDependenciesDialog extends MessageDialog {
+	Text fModuleArgumentsText;
+	String fOriginalText;
+	ILaunchConfiguration flaunchConfiguration;
+
+
+	public OverrideDependenciesDialog(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, int dialogImageType, String[] dialogButtonLabels, int defaultIndex, ILaunchConfiguration config) {
+		super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels, defaultIndex);
+		flaunchConfiguration = config;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.MessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite)
+	 */
+	@Override
+	protected Control createCustomArea(Composite parent) {
+		Composite comp = new Composite(parent, SWT.NONE);
+		comp.setLayout(new GridLayout());
+		Font font = parent.getFont();
+		Group group = new Group(comp, SWT.NONE);
+		GridLayout topLayout = new GridLayout();
+		group.setLayout(topLayout);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.heightHint = convertHeightInCharsToPixels(15);
+		gd.widthHint = convertWidthInCharsToPixels(45);
+		group.setLayoutData(gd);
+		group.setFont(font);
+
+		fModuleArgumentsText = new Text(group, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
+		gd = new GridData(GridData.FILL_BOTH);
+		gd.heightHint = convertHeightInCharsToPixels(10);
+		gd.widthHint = convertWidthInCharsToPixels(35);
+		fModuleArgumentsText.setLayoutData(gd);
+		try {
+			if (!flaunchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_MODULE_CLI_OPTIONS, true)) {
+				String str = flaunchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MODULE_CLI_OPTIONS, "");//$NON-NLS-1$
+				fModuleArgumentsText.setText(str);
+
+			} else {
+				fModuleArgumentsText.setText(JavaRuntime.getModuleCLIOptions(flaunchConfiguration));
+			}
+			fOriginalText = fModuleArgumentsText.getText();
+
+		}
+		catch (CoreException e) {
+			e.printStackTrace();
+		}
+		return comp;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.MessageDialog#buttonPressed(int)
+	 */
+	@Override
+	protected void buttonPressed(int buttonId) {
+		if(buttonId == OK) {
+			if (!fModuleArgumentsText.getText().equals(fOriginalText)) {
+				ILaunchConfigurationWorkingCopy workingCopy;
+				try {
+					workingCopy = flaunchConfiguration.getWorkingCopy();
+					workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_MODULE_CLI_OPTIONS, false);
+					workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MODULE_CLI_OPTIONS, fModuleArgumentsText.getText());
+					workingCopy.doSave();
+				}
+				catch (CoreException e) {
+					e.printStackTrace();
+				}
+			}
+
+		}
+		super.buttonPressed(buttonId);
+	}
+
+
+
+}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RestoreDefaultEntriesAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RestoreDefaultEntriesAction.java
index f05f591..f18eccb 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RestoreDefaultEntriesAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RestoreDefaultEntriesAction.java
@@ -58,6 +58,17 @@
 				copy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
 				getViewer().setEntries(JavaRuntime.computeUnresolvedRuntimeClasspath(copy));
 			}
+			if (!config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_MODULE_CLI_OPTIONS, true)) {
+				ILaunchConfigurationWorkingCopy copy = null;
+				if (config.isWorkingCopy()) {
+					copy = (ILaunchConfigurationWorkingCopy) config;
+				} else {
+					copy = config.getWorkingCopy();
+				}
+				copy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_MODULE_CLI_OPTIONS, true);
+				copy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MODULE_CLI_OPTIONS, ""); //$NON-NLS-1$
+
+			}
 		}
 		catch (CoreException e) {return;}
 	}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java
index 84a0f16..99b1e5e 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java
@@ -224,6 +224,15 @@
 			arguments.add(convertClassPath(cp));
 		}
 
+		String dependencies = config.getOverrideDependencies();
+		if (dependencies != null && dependencies.length() > 0) {
+			String[] parseArguments = DebugPlugin.parseArguments(dependencies);
+			for (String string : parseArguments) {
+				arguments.add(string);
+			}
+
+		}
+
 		if (isModular(config, fVMInstance)) {
 			arguments.add("-m"); //$NON-NLS-1$
 			arguments.add(config.getModuleDescription() + "/" + config.getClassToLaunch()); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java
index 1e9648b..af3dd37 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java
@@ -379,8 +379,7 @@
 			arguments.add("-p"); //$NON-NLS-1$
 			arguments.add(convertClassPath(mp));
 		}
-
-		String[] cp= config.getClassPath();
+		String[] cp = config.getClassPath();
 		int cpidx = -1;
 		if (cp.length > 0) {
 			cpidx = arguments.size();
@@ -388,6 +387,15 @@
 			arguments.add(convertClassPath(cp));
 		}
 
+		String dependencies = config.getOverrideDependencies();
+		if (dependencies != null && dependencies.length() > 0) {
+			String[] parseArguments = DebugPlugin.parseArguments(dependencies);
+			for (String string : parseArguments) {
+				arguments.add(string);
+			}
+
+		}
+
 		if (isModular(config, fVMInstance)) {
 			arguments.add("-m"); //$NON-NLS-1$
 			arguments.add(config.getModuleDescription() + "/" + config.getClassToLaunch()); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java
index 0084dc9..ad5685d 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java
@@ -44,6 +44,7 @@
 import org.eclipse.debug.core.model.IBreakpoint;
 import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
 import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
+import org.eclipse.jdt.core.IClasspathAttribute;
 import org.eclipse.jdt.core.IJavaModelMarker;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.JavaCore;
@@ -1105,4 +1106,20 @@
 	protected final void allowAdvancedSourcelookup() {
 		this.allowAdvancedSourcelookup = true;
 	}
+
+	/**
+	 * Returns the module-related command line options for the configuration that are needed at runtime as equivalents of those options specified by
+	 * {@link IClasspathAttribute}s of the following names:
+	 * <ul>
+	 * <li>{@link IClasspathAttribute#ADD_EXPORTS}</li>
+	 * <li>{@link IClasspathAttribute#ADD_READS}</li>
+	 * <li>{@link IClasspathAttribute#LIMIT_MODULES}</li>
+	 * <li>{@link IClasspathAttribute#PATCH_MODULE}</li>
+	 * </ul>
+	 *
+	 * @since 3.10
+	 */
+	protected String getModuleCLIOptions(ILaunchConfiguration configuration) {
+		return JavaRuntime.getModuleCLIOptions(configuration);
+	}
 }
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
index 46d1419..b036c93 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
@@ -179,7 +179,7 @@
 	 * Launch configuration attribute key. The attribute value is an ordered list of strings which are mementos for runtime module path entries. When
 	 * unspecified, a default modulepath is generated by the dependency provider associated with a launch configuration (via the
 	 * <code>ATTR_CLASSPATH_PROVIDER</code> attribute).
-	 * 
+	 *
 	 * @since 3.10
 	 */
 	public static final String ATTR_MODULEPATH = LaunchingPlugin.getUniqueIdentifier() + ".MODULEPATH"; //$NON-NLS-1$
@@ -199,6 +199,23 @@
 	public static final String ATTR_DEFAULT_CLASSPATH = LaunchingPlugin.getUniqueIdentifier() + ".DEFAULT_CLASSPATH"; //$NON-NLS-1$
 
 	/**
+	 * Launch configuration attribute key. The value is a boolean specifying whether a default build path module cli options should be used when
+	 * launching a local Java application. When <code>false</code>, a module cli option must be specified via the <code>ATTR_MODULE_CLI_OPTIONS</code>
+	 * attribute. When <code>true</code> or unspecified, a classpath is computed by the classpath provider associated with a launch configuration.
+	 *
+	 * @since 3.10
+	 */
+	public static final String ATTR_DEFAULT_MODULE_CLI_OPTIONS = LaunchingPlugin.getUniqueIdentifier() + ".DEFAULT_MODULE_CLI_OPTIONS"; //$NON-NLS-1$
+
+	/**
+	 * Launch configuration attribute key. The value is a string with module cli options if the default is not used for launching a local Java
+	 * application.
+	 *
+	 * @since 3.10
+	 */
+	public static final String ATTR_MODULE_CLI_OPTIONS = LaunchingPlugin.getUniqueIdentifier() + ".MODULE_CLI_OPTIONS"; //$NON-NLS-1$
+
+	/**
 	 * Launch configuration attribute key. The value is an identifier of a
 	 * classpath provider extension used to compute the classpath
 	 * for a launch configuration. When unspecified, the default classpath
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java
index 613602f..8719c84 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaLaunchDelegate.java
@@ -103,6 +103,11 @@
 			} else {
 				// module path
 				runConfig.setModulepath(paths[1]);
+				if (!configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_MODULE_CLI_OPTIONS, true)) {
+					runConfig.setOverrideDependencies(configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MODULE_CLI_OPTIONS, "")); //$NON-NLS-1$
+				} else {
+					runConfig.setOverrideDependencies(getModuleCLIOptions(configuration));
+				}
 			}
 
 			// check for cancellation
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
index c0f6ab8..ec76f9c 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
@@ -66,6 +66,7 @@
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.provisional.JavaModelAccess;
 import org.eclipse.jdt.internal.core.JavaProject;
 import org.eclipse.jdt.internal.launching.CompositeId;
 import org.eclipse.jdt.internal.launching.DefaultEntryResolver;
@@ -3237,4 +3238,96 @@
 		}
 		throw new CoreException(status);
 	}
+
+	private static String PATCH_MODULE = "--" + IClasspathAttribute.PATCH_MODULE; //$NON-NLS-1$
+
+	/**
+	 * Returns the module-related command line options for the configuration that are needed at runtime as equivalents of those options specified by
+	 * {@link IClasspathAttribute}s of the following names:
+	 * <ul>
+	 * <li>{@link IClasspathAttribute#ADD_EXPORTS}</li>
+	 * <li>{@link IClasspathAttribute#ADD_READS}</li>
+	 * <li>{@link IClasspathAttribute#LIMIT_MODULES}</li>
+	 * <li>{@link IClasspathAttribute#PATCH_MODULE}</li>
+	 * </ul>
+	 *
+	 * @since 3.10
+	 */
+	public static String getModuleCLIOptions(ILaunchConfiguration configuration) {
+		StringBuilder cliOptionString = new StringBuilder();
+		try {
+			IRuntimeClasspathEntry[] entries;
+			entries = JavaRuntime.computeUnresolvedRuntimeClasspath(configuration);
+			entries = JavaRuntime.resolveRuntimeClasspath(entries, configuration);
+
+			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+			for (IRuntimeClasspathEntry iRuntimeClasspathEntry : entries) {
+				if (iRuntimeClasspathEntry.getClasspathEntry().getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+					IResource res = root.findMember(iRuntimeClasspathEntry.getClasspathEntry().getPath());
+					IJavaProject jp = (IJavaProject) JavaCore.create(res);
+					IClasspathEntry[] rawClasspath = jp.getRawClasspath();
+					for (IClasspathEntry iClasspathEntry : rawClasspath) {
+						if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+							if (JavaRuntime.JRE_CONTAINER.equals(iClasspathEntry.getPath().segment(0))) {
+								String cliOptions = JavaModelAccess.getModuleCLIOptions(jp, iClasspathEntry);
+								String str11 = cliOptions;
+								int index = cliOptions.indexOf(":"); //$NON-NLS-1$
+								StringBuffer cliOptionBuffer = new StringBuffer();
+								if ( index != -1) {
+									String[] splited = str11.split("\\s+"); //$NON-NLS-1$
+									int i = 0;
+									for (String string : splited) {
+										if (string.equals(PATCH_MODULE)) {
+											cliOptionBuffer.append(" "); //$NON-NLS-1$
+											cliOptionBuffer.append(string);
+											i++;
+											continue;
+										}
+										if (i > 0) {
+											if (splited[i - 1].equals(PATCH_MODULE)) {
+												cliOptionBuffer.append(" "); //$NON-NLS-1$
+												cliOptionBuffer.append(string);
+												i++;
+												continue;
+											}
+										}
+										index = string.indexOf(":"); //$NON-NLS-1$
+										if (index == -1) {
+											if (i > 0) {
+												cliOptionBuffer.append(" "); //$NON-NLS-1$
+											}
+											cliOptionBuffer.append(string);
+
+										} else {
+											String[] splited1 = string.split(":"); //$NON-NLS-1$
+											int j = 0;
+											for (String string2 : splited1) {
+												if (j > 0) {
+													cliOptionBuffer.append(" "); //$NON-NLS-1$
+													cliOptionBuffer.append(splited[i - 1]);
+												}
+												cliOptionBuffer.append(" "); //$NON-NLS-1$
+												cliOptionBuffer.append(string2);
+												j++;
+											}
+										}
+										i++;
+									}
+								}
+								else {
+									cliOptionBuffer.append(cliOptions);
+								}
+								cliOptionString.append(cliOptionBuffer);
+							}
+						}
+					}
+
+				}
+			}
+		}
+		catch (CoreException e) {
+			e.printStackTrace();
+		}
+		return cliOptionString.toString().trim();
+	}
 }
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/VMRunnerConfiguration.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/VMRunnerConfiguration.java
index 390bd5d..bd86a0a 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/VMRunnerConfiguration.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/VMRunnerConfiguration.java
@@ -34,6 +34,7 @@
 	private String[] fModulepath;
 	private String fModuleDescription;
 	private String fWorkingDirectory;
+	private String fOverrideDependencies;
 	private Map<String, Object> fVMSpecificAttributesMap;
 	private boolean fResume = true;
 
@@ -308,4 +309,26 @@
 	public String getModuleDescription() {
 		return this.fModuleDescription;
 	}
+
+	/**
+	 * Gets the fOverrideDependencies.
+	 * 
+	 * @return the fOverrideDependencies
+	 * @since 3.10
+	 */
+	public String getOverrideDependencies() {
+		return fOverrideDependencies;
+	}
+
+	/**
+	 * Sets the fOverrideDependencies.
+	 * 
+	 * @param fOverrideDependencies
+	 *            the fOverrideDependencies to set
+	 * @since 3.10
+	 */
+	public void setOverrideDependencies(String fOverrideDependencies) {
+		this.fOverrideDependencies = fOverrideDependencies;
+	}
+
 }