Bug 32205 - [console] Add launch option to merge process output

Also make use of output merge option in external tool launch.

Change-Id: Ibc3cec8df076a4cea3f83e37fa2640115dd3f49b
Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
diff --git a/org.eclipse.core.externaltools/plugin.xml b/org.eclipse.core.externaltools/plugin.xml
index 29142ab..b60e930 100644
--- a/org.eclipse.core.externaltools/plugin.xml
+++ b/org.eclipse.core.externaltools/plugin.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?eclipse version="3.4"?>
 <!--
-    Copyright (c) 2005, 2010 IBM Corporation and others.
+    Copyright (c) 2005, 2019 IBM Corporation and others.
 
     This program and the accompanying materials
     are made available under the terms of the Eclipse Public License 2.0
@@ -22,14 +22,16 @@
             delegate="org.eclipse.core.externaltools.internal.launchConfigurations.ProgramLaunchDelegate"
             category="org.eclipse.ui.externaltools"
             modes="run"
-            id="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
+            id="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType"
+            allowOutputMerging="true">
       </launchConfigurationType>
       <launchConfigurationType
             name="%Program.externalTools"
             delegate="org.eclipse.core.externaltools.internal.launchConfigurations.ProgramLaunchDelegate"
             category="org.eclipse.ui.externaltools.builder"
             modes="run"
-            id="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
+            id="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType"
+            allowOutputMerging="true">
       </launchConfigurationType>
    </extension>
    <extension
diff --git a/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ProgramLaunchDelegate.java b/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ProgramLaunchDelegate.java
index 1abe8c1..b7a0e29 100644
--- a/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ProgramLaunchDelegate.java
+++ b/org.eclipse.core.externaltools/src/org/eclipse/core/externaltools/internal/launchConfigurations/ProgramLaunchDelegate.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -50,6 +50,17 @@
 	private static final String ATTR_LAUNCH_IN_BACKGROUND = "org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND"; //$NON-NLS-1$
 
 	/**
+	 * Launch configuration attribute - a boolean value indicating whether a
+	 * configuration should be launched with merged error and standard output.
+	 * Default value is <code>false</code>.
+	 * <p>
+	 * This constant is defined in org.eclipse.debug.ui, but has to be copied
+	 * here to support headless launching.
+	 * </p>
+	 */
+	private static final String ATTR_MERGE_OUTPUT = "org.eclipse.debug.ui.ATTR_MERGE_OUTPUT"; //$NON-NLS-1$
+
+	/**
 	 * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration,
 	 *      java.lang.String, org.eclipse.debug.core.ILaunch,
 	 *      org.eclipse.core.runtime.IProgressMonitor)
@@ -110,7 +121,8 @@
 			return;
 		}
 
-		Process p = DebugPlugin.exec(cmdLine, workingDir, envp);
+		boolean mergeOutput = configuration.getAttribute(ATTR_MERGE_OUTPUT, false);
+		Process p = DebugPlugin.exec(cmdLine, workingDir, envp, mergeOutput);
 		IProcess process = null;
 
 		// add process type to process attributes
diff --git a/org.eclipse.debug.core/META-INF/MANIFEST.MF b/org.eclipse.debug.core/META-INF/MANIFEST.MF
index 0efbd67..820ddc8 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.13.400.qualifier
+Bundle-Version: 3.14.0.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/DebugPlugin.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java
index b1d681e..c113351 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -868,12 +868,60 @@
 	 * @since 3.0
 	 */
 	public static Process exec(String[] cmdLine, File workingDirectory, String[] envp) throws CoreException {
-		Process p= null;
+		return exec(cmdLine, workingDirectory, envp, false);
+	}
+
+	/**
+	 * Convenience method that performs a runtime exec on the given command line
+	 * in the context of the specified working directory, and returns the
+	 * resulting process. If the current runtime does not support the
+	 * specification of a working directory, the status handler for error code
+	 * <code>ERR_WORKING_DIRECTORY_NOT_SUPPORTED</code> is queried to see if the
+	 * exec should be re-executed without specifying a working directory.
+	 *
+	 * @param cmdLine the command line
+	 * @param workingDirectory the working directory, or <code>null</code>
+	 * @param envp the environment variables set in the process, or
+	 *            <code>null</code>
+	 * @param mergeOutput if <code>true</code> the error stream will be merged
+	 *            with standard output stream and both can be read through the
+	 *            same output stream
+	 * @return the resulting process or <code>null</code> if the exec is
+	 *         canceled
+	 * @exception CoreException if the exec fails
+	 * @see Runtime
+	 *
+	 * @since 3.14
+	 */
+	public static Process exec(String[] cmdLine, File workingDirectory, String[] envp, boolean mergeOutput) throws CoreException {
+		Process p = null;
 		try {
-			if (workingDirectory == null) {
-				p= Runtime.getRuntime().exec(cmdLine, envp);
+			// starting with and without merged output could be done with the
+			// same process builder approach but since the handling of
+			// environment variables is slightly different between
+			// ProcessBuilder and Runtime.exec only the new option uses process
+			// builder to not break existing caller of this method
+			if (mergeOutput) {
+				ProcessBuilder pb = new ProcessBuilder(cmdLine);
+				pb.directory(workingDirectory);
+				pb.redirectErrorStream(mergeOutput);
+				if (envp != null) {
+					Map<String, String> env = pb.environment();
+					env.clear();
+					for (String e : envp) {
+						int index = e.indexOf('=');
+						if (index != -1) {
+							env.put(e.substring(0, index), e.substring(index + 1));
+						}
+					}
+				}
+				p = pb.start();
 			} else {
-				p= Runtime.getRuntime().exec(cmdLine, envp, workingDirectory);
+				if (workingDirectory == null) {
+					p = Runtime.getRuntime().exec(cmdLine, envp);
+				} else {
+					p = Runtime.getRuntime().exec(cmdLine, envp, workingDirectory);
+				}
 			}
 		} catch (IOException e) {
 			Status status = new Status(IStatus.ERROR, getUniqueIdentifier(), ERROR, DebugCoreMessages.DebugPlugin_0, e);
@@ -885,8 +933,8 @@
 
 			if (handler != null) {
 				Object result = handler.handleStatus(status, null);
-				if (result instanceof Boolean && ((Boolean)result).booleanValue()) {
-					p= exec(cmdLine, null);
+				if (result instanceof Boolean && ((Boolean) result).booleanValue()) {
+					p = exec(cmdLine, null);
 				}
 			}
 		}
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationType.java b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationType.java
index f28c69f..094f7f2 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationType.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/core/ILaunchConfigurationType.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -374,4 +374,14 @@
 	 * @since 3.13
 	 */
 	boolean supportsCommandLine();
+
+	/**
+	 * Returns whether this type of launch configuration supports launching
+	 * processes with error stream redirected and merged with standard output
+	 * stream.
+	 *
+	 * @return whether this kind of launch configuration supports output merging
+	 * @since 3.14
+	 */
+	boolean supportsOutputMerging();
 }
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IConfigurationElementConstants.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IConfigurationElementConstants.java
index b77c5c9..ad8c42b 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IConfigurationElementConstants.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/IConfigurationElementConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2018 IBM Corporation and others.
+ * Copyright (c) 2006, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -365,4 +365,14 @@
 	 * @since 3.13
 	 */
 	String ALLOW_COMMANDLINE = "allowCommandLine"; //$NON-NLS-1$
+
+	/**
+	 * The allowOutputMerging node name for a configuration element
+	 * <p>
+	 * Equal to the word: <code>allowOutputMerging</code>
+	 * </p>
+	 *
+	 * @since 3.14
+	 */
+	String ALLOW_OUTPUT_MERGING = "allowOutputMerging"; //$NON-NLS-1$
 }
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationType.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationType.java
index ee5cfb8..5ced04c 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationType.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchConfigurationType.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -494,5 +494,16 @@
 		}
 		return false;
 	}
+
+	@Override
+	public boolean supportsOutputMerging() {
+		String allowOutputMergingString = fElement.getAttribute(IConfigurationElementConstants.ALLOW_OUTPUT_MERGING);
+		if (allowOutputMergingString != null) {
+			if (allowOutputMergingString.equalsIgnoreCase("true")) { //$NON-NLS-1$
+				return true;
+			}
+		}
+		return false;
+	}
 }
 
diff --git a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchDelegate.java b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchDelegate.java
index c63e0aa..303d378 100644
--- a/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchDelegate.java
+++ b/org.eclipse.debug.core/core/org/eclipse/debug/internal/core/LaunchDelegate.java
@@ -30,23 +30,28 @@
 import com.ibm.icu.text.MessageFormat;
 
 /**
- * Proxy to a launch delegate extension
- * Clients can contribute launch delegates through the <code>launchDelegates</code> extension point
- *
+ * Proxy to a launch delegate extension.
+ * <p>
+ * Clients can contribute launch delegates through the
+ * <code>launchDelegates</code> extension point
+ * </p>
+ * <p>
  * Example contribution of the local java launch delegate
+ * </p>
+ *
  * <pre>
- * <extension point="org.eclipse.debug.core.launchDelegates">
-      <launchDelegate
-            delegate="org.eclipse.jdt.launching.JavaLaunchDelegate"
-            id="org.eclipse.jdt.launching.localJavaApplicationDelegate"
-            modes="run, debug"
-            name="%localJavaApplication"
-            type="org.eclipse.jdt.launching.localJavaApplication">
-          <modeCombination
-    		modes="run, profile">
-    		perspective="com.example.Perspective">
-   		  </modeCombination>
-      </launchDelegate>
+ * &lt;extension point="org.eclipse.debug.core.launchDelegates"&gt;
+ *    &lt;launchDelegate
+ *          delegate="org.eclipse.jdt.launching.JavaLaunchDelegate"
+ *          id="org.eclipse.jdt.launching.localJavaApplicationDelegate"
+ *          modes="run, debug"
+ *          name="%localJavaApplication"
+ *          type="org.eclipse.jdt.launching.localJavaApplication"&gt;
+ *        &lt;modeCombination
+ *          modes="run, profile"&gt;
+ *          perspective="com.example.Perspective"&gt;
+ *        &lt;/modeCombination&gt;
+ *    &lt;/launchDelegate&gt;
  * </pre>
  *
  * Clients are NOT intended to subclass this class
diff --git a/org.eclipse.debug.core/pom.xml b/org.eclipse.debug.core/pom.xml
index 7784584..bc7fdee 100644
--- a/org.eclipse.debug.core/pom.xml
+++ b/org.eclipse.debug.core/pom.xml
@@ -18,6 +18,6 @@
   </parent>
   <groupId>org.eclipse.debug</groupId>
   <artifactId>org.eclipse.debug.core</artifactId>
-  <version>3.13.400-SNAPSHOT</version>
+  <version>3.14.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/org.eclipse.debug.core/schema/launchConfigurationTypes.exsd b/org.eclipse.debug.core/schema/launchConfigurationTypes.exsd
index 94d883b..b16af6f 100644
--- a/org.eclipse.debug.core/schema/launchConfigurationTypes.exsd
+++ b/org.eclipse.debug.core/schema/launchConfigurationTypes.exsd
@@ -170,6 +170,14 @@
                </documentation>
             </annotation>
          </attribute>
+         <attribute name="allowOutputMerging" type="boolean">
+            <annotation>
+               <documentation>
+                  specifies whether this launch configuration type supports output merging. A launch configuration which singals support must check the launch configuration attribute "org.eclipse.debug.ui.ATTR_MERGE_OUTPUT" and if its value is true perform the launch in a way that stderr and stdout are merged and both can be read through stdout.
+                  Defaults to &lt;code&gt;false&lt;/code&gt; if not specified. This attribute was added in 4.13 release.
+               </documentation>
+            </annotation>
+         </attribute>
       </complexType>
    </element>
 
@@ -255,7 +263,7 @@
          <meta.section type="copyright"/>
       </appinfo>
       <documentation>
-         Copyright (c) 2000, 2018 IBM Corporation and others.&lt;br&gt;
+         Copyright (c) 2000, 2019 IBM Corporation and others.&lt;br&gt;
 
 This program and the accompanying materials are made 
 available under the terms of the Eclipse Public License 2.0 which 
diff --git a/org.eclipse.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.debug.ui/META-INF/MANIFEST.MF
index 17c582b..539cd0a 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.14.200.qualifier
+Bundle-Version: 3.15.0.qualifier
 Bundle-Activator: org.eclipse.debug.internal.ui.DebugUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/org.eclipse.debug.ui/pom.xml b/org.eclipse.debug.ui/pom.xml
index fb42dfb..ff0d260 100644
--- a/org.eclipse.debug.ui/pom.xml
+++ b/org.eclipse.debug.ui/pom.xml
@@ -19,7 +19,7 @@
   </parent>
   <groupId>org.eclipse.debug</groupId>
   <artifactId>org.eclipse.debug.ui</artifactId>
-  <version>3.14.200-SNAPSHOT</version>
+  <version>3.15.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
   <properties>
     <code.ignoredWarnings>-warn:+resource,-deprecation,unavoidableGenericProblems</code.ignoredWarnings>
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.java
index 3588aa7..d2ed415 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.java
@@ -46,6 +46,7 @@
 	public static String CommonTab_19;
 	public static String CommonTab_2;
 	public static String CommonTab_20;
+	public static String CommonTab_21;
 	public static String CommonTab_3;
 	public static String CommonTab_4;
 	public static String CommonTab_5;
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.properties b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.properties
index 7a3a36d..f042a9e 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.properties
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsMessages.properties
@@ -39,6 +39,7 @@
 CommonTab_19=File System...
 CommonTab_2=Defa&ult - inherited ({0})
 CommonTab_20=Variables...
+CommonTab_21=&Merge standard and error output (disables coloring of error output)
 CommonTab_3=Oth&er
 CommonTab_4=Standard Input and Output
 CommonTab_5=&Allocate console (necessary for input)
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/CommonTab.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/CommonTab.java
index 9ac350d..8f1191a 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/CommonTab.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/CommonTab.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -123,21 +123,23 @@
 	private static final String BAD_CONTAINER = "bad_container_name"; //$NON-NLS-1$
 
 	// Local/shared UI widgets
+	private Composite fIoComposit;
 	private Button fLocalRadioButton;
 	private Button fSharedRadioButton;
 	private Text fSharedLocationText;
 	private Button fSharedLocationButton;
 	private Button fLaunchInBackgroundButton;
-	private Button fDefaultEncodingButton;
-	private Button fAltEncodingButton;
-	private Combo fEncodingCombo;
+    private Button fDefaultEncodingButton;
+    private Button fAltEncodingButton;
+    private Combo fEncodingCombo;
 	private Button fConsoleOutput;
-	private Button fFileOutput;
-	private Button fFileBrowse;
-	private Text fFileText;
-	private Button fVariables;
-	private Button fAppend;
-	private Button fWorkspaceBrowse;
+    private Button fFileOutput;
+    private Button fFileBrowse;
+    private Text fFileText;
+    private Button fVariables;
+    private Button fAppend;
+	private Button fMergeOutput;
+    private Button fWorkspaceBrowse;
 
 	private Button fInputFileCheckButton;
 	private Text fInputFileLocationText;
@@ -160,7 +162,7 @@
 		}
 	};
 
-	/**
+    /**
 	 * Constructs a new tab with default context help.
 	 */
 	public CommonTab() {
@@ -260,96 +262,97 @@
 		setSharedEnabled(false);
 	}
 
-	/**
-	 * Creates the component set for the capture output composite
-	 * @param parent the parent to add this component to
-	 */
+    /**
+     * Creates the component set for the capture output composite
+     * @param parent the parent to add this component to
+     */
 	private void createOutputCaptureComponent(Composite parent) {
-		Group group = SWTFactory.createGroup(parent, LaunchConfigurationsMessages.CommonTab_4, 5, 2, GridData.FILL_HORIZONTAL);
+        Group group = SWTFactory.createGroup(parent, LaunchConfigurationsMessages.CommonTab_4, 5, 2, GridData.FILL_HORIZONTAL);
 		createInputCaptureComponent(group);
 		Composite comp = SWTFactory.createComposite(group, group.getFont(), 5, 5, GridData.FILL_BOTH, 0, 0);
+		fIoComposit = comp;
 		fFileOutput = createCheckButton(comp, LaunchConfigurationsMessages.CommonTab_6);
-		fFileOutput.setLayoutData(new GridData(SWT.BEGINNING, SWT.NORMAL, false, false));
-		fFileOutput.addSelectionListener(new SelectionAdapter() {
-			@Override
+        fFileOutput.setLayoutData(new GridData(SWT.BEGINNING, SWT.NORMAL, false, false));
+        fFileOutput.addSelectionListener(new SelectionAdapter() {
+            @Override
 			public void widgetSelected(SelectionEvent e) {
-				enableOuputCaptureWidgets(fFileOutput.getSelection());
-				updateLaunchConfigurationDialog();
-			}
-		});
-		fFileText = SWTFactory.createSingleText(comp, 4);
-		fFileText.getAccessible().addAccessibleListener(new AccessibleAdapter() {
-			@Override
+                enableOuputCaptureWidgets(fFileOutput.getSelection());
+                updateLaunchConfigurationDialog();
+            }
+        });
+        fFileText = SWTFactory.createSingleText(comp, 4);
+        fFileText.getAccessible().addAccessibleListener(new AccessibleAdapter() {
+        	@Override
 			public void getName(AccessibleEvent e) {
-				e.result = LaunchConfigurationsMessages.CommonTab_6;
-			}
-		});
-		fFileText.addModifyListener(fBasicModifyListener);
+        		e.result = LaunchConfigurationsMessages.CommonTab_6;
+        	}
+        });
+        fFileText.addModifyListener(fBasicModifyListener);
 
-		Composite bcomp = SWTFactory.createComposite(comp, 3, 5, GridData.HORIZONTAL_ALIGN_END);
+        Composite bcomp = SWTFactory.createComposite(comp, 3, 5, GridData.HORIZONTAL_ALIGN_END);
 		GridLayout ld = (GridLayout)bcomp.getLayout();
-		ld.marginHeight = 1;
-		ld.marginWidth = 0;
-		fWorkspaceBrowse = createPushButton(bcomp, LaunchConfigurationsMessages.CommonTab_12, null);
-		fWorkspaceBrowse.addSelectionListener(new SelectionAdapter() {
-			@Override
+        ld.marginHeight = 1;
+        ld.marginWidth = 0;
+        fWorkspaceBrowse = createPushButton(bcomp, LaunchConfigurationsMessages.CommonTab_12, null);
+        fWorkspaceBrowse.addSelectionListener(new SelectionAdapter() {
+            @Override
 			public void widgetSelected(SelectionEvent e) {
-				ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
-				dialog.setTitle(LaunchConfigurationsMessages.CommonTab_13);
-				dialog.setMessage(LaunchConfigurationsMessages.CommonTab_14);
-				dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
-				dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
-				dialog.setDialogBoundsSettings(getDialogBoundsSettings(WORKSPACE_SELECTION_DIALOG), Dialog.DIALOG_PERSISTSIZE);
-				if (dialog.open() == IDialogConstants.OK_ID) {
-					IResource resource = (IResource) dialog.getFirstResult();
-					if(resource != null) {
-						String arg = resource.getFullPath().toString();
-						String fileLoc = VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", arg); //$NON-NLS-1$
-						fFileText.setText(fileLoc);
-					}
-				}
-			}
-		});
-		fFileBrowse = createPushButton(bcomp, LaunchConfigurationsMessages.CommonTab_7, null);
-		fFileBrowse.addSelectionListener(new SelectionAdapter() {
-			@Override
+                ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
+                dialog.setTitle(LaunchConfigurationsMessages.CommonTab_13);
+                dialog.setMessage(LaunchConfigurationsMessages.CommonTab_14);
+                dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
+                dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
+                dialog.setDialogBoundsSettings(getDialogBoundsSettings(WORKSPACE_SELECTION_DIALOG), Dialog.DIALOG_PERSISTSIZE);
+                if (dialog.open() == IDialogConstants.OK_ID) {
+                    IResource resource = (IResource) dialog.getFirstResult();
+                    if(resource != null) {
+                    	String arg = resource.getFullPath().toString();
+                    	String fileLoc = VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", arg); //$NON-NLS-1$
+                    	fFileText.setText(fileLoc);
+                    }
+                }
+            }
+        });
+        fFileBrowse = createPushButton(bcomp, LaunchConfigurationsMessages.CommonTab_7, null);
+        fFileBrowse.addSelectionListener(new SelectionAdapter() {
+            @Override
 			public void widgetSelected(SelectionEvent e) {
-				String filePath = fFileText.getText();
+                String filePath = fFileText.getText();
 				FileDialog dialog = new FileDialog(getShell(), SWT.SAVE | SWT.SHEET);
-				filePath = dialog.open();
-				if (filePath != null) {
-					fFileText.setText(filePath);
-				}
-			}
-		});
-		fVariables = createPushButton(bcomp, LaunchConfigurationsMessages.CommonTab_9, null);
-		fVariables.addSelectionListener(new SelectionListener() {
-			@Override
+                filePath = dialog.open();
+                if (filePath != null) {
+                    fFileText.setText(filePath);
+                }
+            }
+        });
+        fVariables = createPushButton(bcomp, LaunchConfigurationsMessages.CommonTab_9, null);
+        fVariables.addSelectionListener(new SelectionListener() {
+            @Override
 			public void widgetSelected(SelectionEvent e) {
-				StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell());
+                StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell());
 				dialog.open();
 				String variable = dialog.getVariableExpression();
 				if (variable != null) {
 					fFileText.insert(variable);
 				}
-			}
-			@Override
+            }
+            @Override
 			public void widgetDefaultSelected(SelectionEvent e) {}
-		});
-		fAppend = createCheckButton(comp, LaunchConfigurationsMessages.CommonTab_11);
+        });
+        fAppend = createCheckButton(comp, LaunchConfigurationsMessages.CommonTab_11);
 
 		GridData gd = new GridData(SWT.LEFT, SWT.TOP, true, false);
-		gd.horizontalSpan = 4;
-		fAppend.setLayoutData(gd);
+		gd.horizontalSpan = 5;
+        fAppend.setLayoutData(gd);
 		fAppend.addSelectionListener(new SelectionAdapter() {
-			@Override
+		    @Override
 			public void widgetSelected(SelectionEvent e) {
-				updateLaunchConfigurationDialog();
-			}
+		        updateLaunchConfigurationDialog();
+		    }
 		});
-	}
+    }
 
-	private void createInputCaptureComponent(Composite parent){
+    private void createInputCaptureComponent(Composite parent){
 		Composite comp1 = SWTFactory.createComposite(parent, parent.getFont(), 5, 5, GridData.FILL_BOTH, 0, 0);
 		fConsoleOutput = createCheckButton(comp1, LaunchConfigurationsMessages.CommonTab_5);
 		fConsoleOutput.addSelectionListener(new SelectionAdapter() {
@@ -450,30 +453,30 @@
 		});
 
 		setInputFileEnabled(false);
-	}
-	/**
-	 * Enables or disables the output capture widgets based on the the specified enablement
-	 * @param enable if the output capture widgets should be enabled or not
-	 * @since 3.2
-	 */
-	private void enableOuputCaptureWidgets(boolean enable) {
-		fFileText.setEnabled(enable);
-		fFileBrowse.setEnabled(enable);
-		fWorkspaceBrowse.setEnabled(enable);
-		fVariables.setEnabled(enable);
-		fAppend.setEnabled(enable);
-	}
+    }
+    /**
+     * Enables or disables the output capture widgets based on the the specified enablement
+     * @param enable if the output capture widgets should be enabled or not
+     * @since 3.2
+     */
+    private void enableOuputCaptureWidgets(boolean enable) {
+    	fFileText.setEnabled(enable);
+        fFileBrowse.setEnabled(enable);
+        fWorkspaceBrowse.setEnabled(enable);
+        fVariables.setEnabled(enable);
+        fAppend.setEnabled(enable);
+    }
 
-	/**
-	 * Returns the default encoding for the specified config
-	 * @param config the configuration to get the encoding for
-	 * @return the default encoding
-	 *
-	 * @since 3.4
-	 */
-	private String getDefaultEncoding(ILaunchConfiguration config) {
-		try {
-			IResource[] resources = config.getMappedResources();
+    /**
+     * Returns the default encoding for the specified config
+     * @param config the configuration to get the encoding for
+     * @return the default encoding
+     *
+     * @since 3.4
+     */
+    private String getDefaultEncoding(ILaunchConfiguration config) {
+    	try {
+	    	IResource[] resources = config.getMappedResources();
 			if(resources != null && resources.length > 0) {
 				IResource res = resources[0];
 				if(res instanceof IFile) {
@@ -483,62 +486,62 @@
 					return ((IContainer)res).getDefaultCharset();
 				}
 			}
-		}
-		catch(CoreException ce) {
-			DebugUIPlugin.log(ce);
-		}
-		return ResourcesPlugin.getEncoding();
-	}
+    	}
+    	catch(CoreException ce) {
+    		DebugUIPlugin.log(ce);
+    	}
+    	return ResourcesPlugin.getEncoding();
+    }
 
-	/**
-	 * Creates the encoding component
-	 * @param parent the parent to add this composite to
-	 */
-	private void createEncodingComponent(Composite parent) {
-		Group group = SWTFactory.createGroup(parent, LaunchConfigurationsMessages.CommonTab_1, 2, 1, GridData.FILL_BOTH);
+    /**
+     * Creates the encoding component
+     * @param parent the parent to add this composite to
+     */
+    private void createEncodingComponent(Composite parent) {
+	    Group group = SWTFactory.createGroup(parent, LaunchConfigurationsMessages.CommonTab_1, 2, 1, GridData.FILL_BOTH);
 
-		fDefaultEncodingButton = createRadioButton(group, IInternalDebugCoreConstants.EMPTY_STRING);
-		GridData gd = new GridData(SWT.BEGINNING, SWT.NORMAL, true, false);
-		gd.horizontalSpan = 2;
-		fDefaultEncodingButton.setLayoutData(gd);
+	    fDefaultEncodingButton = createRadioButton(group, IInternalDebugCoreConstants.EMPTY_STRING);
+	    GridData gd = new GridData(SWT.BEGINNING, SWT.NORMAL, true, false);
+	    gd.horizontalSpan = 2;
+	    fDefaultEncodingButton.setLayoutData(gd);
 
-		fAltEncodingButton = createRadioButton(group, LaunchConfigurationsMessages.CommonTab_3);
-		fAltEncodingButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+	    fAltEncodingButton = createRadioButton(group, LaunchConfigurationsMessages.CommonTab_3);
+	    fAltEncodingButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
 
-		fEncodingCombo = new Combo(group, SWT.NONE);
-		fEncodingCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		fEncodingCombo.setFont(parent.getFont());
-		List<String> allEncodings = IDEEncoding.getIDEEncodings();
-		String[] encodingArray = allEncodings.toArray(new String[0]);
-		fEncodingCombo.setItems(encodingArray);
-		if (encodingArray.length > 0) {
-			fEncodingCombo.select(0);
-		}
-		fEncodingCombo.getAccessible().addAccessibleListener(new AccessibleAdapter() {
-			@Override
+	    fEncodingCombo = new Combo(group, SWT.NONE);
+	    fEncodingCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+	    fEncodingCombo.setFont(parent.getFont());
+	    List<String> allEncodings = IDEEncoding.getIDEEncodings();
+        String[] encodingArray = allEncodings.toArray(new String[0]);
+	    fEncodingCombo.setItems(encodingArray);
+        if (encodingArray.length > 0) {
+            fEncodingCombo.select(0);
+        }
+        fEncodingCombo.getAccessible().addAccessibleListener(new AccessibleAdapter() {
+        	@Override
 			public void getName(AccessibleEvent e) {
-				e.result = LaunchConfigurationsMessages.CommonTab_3;
-			}
-		});
-		SelectionListener listener = new SelectionAdapter() {
-			@Override
+        		e.result = LaunchConfigurationsMessages.CommonTab_3;
+        	}
+        });
+	    SelectionListener listener = new SelectionAdapter() {
+	        @Override
 			public void widgetSelected(SelectionEvent e) {
-				if(e.getSource() instanceof Button) {
-					Button button = (Button)e.getSource();
-					if(button.getSelection()) {
-						updateLaunchConfigurationDialog();
-						fEncodingCombo.setEnabled(fAltEncodingButton.getSelection() == true);
-					}
-				}
-				else {
-					updateLaunchConfigurationDialog();
-				}
-			}
-		};
-		fAltEncodingButton.addSelectionListener(listener);
-		fDefaultEncodingButton.addSelectionListener(listener);
-		fEncodingCombo.addSelectionListener(listener);
-		fEncodingCombo.addKeyListener(new KeyAdapter() {
+	        	if(e.getSource() instanceof Button) {
+	        		Button button = (Button)e.getSource();
+	        		if(button.getSelection()) {
+		        		updateLaunchConfigurationDialog();
+			            fEncodingCombo.setEnabled(fAltEncodingButton.getSelection() == true);
+	        		}
+	        	}
+	        	else {
+	        		updateLaunchConfigurationDialog();
+	        	}
+	        }
+	    };
+	    fAltEncodingButton.addSelectionListener(listener);
+	    fDefaultEncodingButton.addSelectionListener(listener);
+	    fEncodingCombo.addSelectionListener(listener);
+	    fEncodingCombo.addKeyListener(new KeyAdapter() {
 			@Override
 			public void keyReleased(KeyEvent e) {
 				scheduleUpdateJob();
@@ -658,9 +661,9 @@
 		String currentContainerString = fSharedLocationText.getText();
 		IContainer currentContainer = getContainer(currentContainerString);
 		ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(),
-					currentContainer,
-					false,
-					LaunchConfigurationsMessages.CommonTab_Select_a_location_for_the_launch_configuration_13);
+				   currentContainer,
+				   false,
+				   LaunchConfigurationsMessages.CommonTab_Select_a_location_for_the_launch_configuration_13);
 		dialog.showClosedProjects(false);
 		dialog.setDialogBoundsSettings(getDialogBoundsSettings(SHARED_LAUNCH_CONFIGURATON_DIALOG), Dialog.DIALOG_PERSISTSIZE);
 		dialog.open();
@@ -706,33 +709,54 @@
 		updateConsoleOutput(configuration);
 	}
 
-	/**
-	 * Updates the console output form the local configuration
-	 * @param configuration the local configuration
-	 */
-	private void updateConsoleOutput(ILaunchConfiguration configuration) {
-		boolean outputToConsole = true;
+    /**
+     * Updates the console output form the local configuration
+     * @param configuration the local configuration
+     */
+    private void updateConsoleOutput(ILaunchConfiguration configuration) {
+        boolean outputToConsole = true;
 		String stdinFromFile = null;
-		String outputFile = null;
-		boolean append = false;
+        String outputFile = null;
+        boolean append = false;
+		boolean mergeOutput = false;
+		boolean supportsMergeOutput = false;
 
-		try {
-			outputToConsole = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, true);
+        try {
+            outputToConsole = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, true);
 			stdinFromFile = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_STDIN_FILE, (String) null);
 
-			outputFile = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, (String)null);
-			append = configuration.getAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, false);
-		} catch (CoreException e) {
-		}
+            outputFile = configuration.getAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, (String)null);
+            append = configuration.getAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, false);
+			mergeOutput = configuration.getAttribute(IDebugUIConstants.ATTR_MERGE_OUTPUT, false);
+			supportsMergeOutput = configuration.getType().supportsOutputMerging();
+        } catch (CoreException e) {
+        }
 
 		fConsoleOutput.setSelection(outputToConsole);
-		fAppend.setSelection(append);
-		boolean haveOutputFile= outputFile != null;
-		if (haveOutputFile) {
-			fFileText.setText(outputFile);
+        fAppend.setSelection(append);
+		if (supportsMergeOutput) {
+			fMergeOutput = createCheckButton(fIoComposit, LaunchConfigurationsMessages.CommonTab_21);
+			GridData gd = new GridData(SWT.LEFT, SWT.TOP, true, false);
+			gd.horizontalSpan = 5;
+			fMergeOutput.setLayoutData(gd);
+			fMergeOutput.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					updateLaunchConfigurationDialog();
+				}
+			});
+			fMergeOutput.setSelection(mergeOutput);
 		}
-		fFileOutput.setSelection(haveOutputFile);
-		enableOuputCaptureWidgets(haveOutputFile);
+		else if (fMergeOutput != null) {
+			fMergeOutput.dispose();
+			fMergeOutput = null;
+		}
+        boolean haveOutputFile= outputFile != null;
+        if (haveOutputFile) {
+            fFileText.setText(outputFile);
+        }
+        fFileOutput.setSelection(haveOutputFile);
+        enableOuputCaptureWidgets(haveOutputFile);
 
 		boolean haveInputFile = stdinFromFile != null;
 		if (haveInputFile) {
@@ -740,13 +764,13 @@
 		}
 		fInputFileCheckButton.setSelection(haveInputFile);
 		setInputFileEnabled(haveInputFile);
-	}
+    }
 
-	/**
-	 * Updates the launch on background check button
-	 * @param configuration the local launch configuration
-	 */
-	protected void updateLaunchInBackground(ILaunchConfiguration configuration) {
+    /**
+     * Updates the launch on background check button
+     * @param configuration the local launch configuration
+     */
+    protected void updateLaunchInBackground(ILaunchConfiguration configuration) {
 		fLaunchInBackgroundButton.setSelection(isLaunchInBackground(configuration));
 	}
 
@@ -755,24 +779,24 @@
 	 * @param configuration the local configuration
 	 */
 	private void updateEncoding(ILaunchConfiguration configuration) {
-		String encoding = null;
-		try {
-			encoding = configuration.getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, (String)null);
-		} catch (CoreException e) {
-		}
-		String defaultEncoding = getDefaultEncoding(configuration);
+	    String encoding = null;
+	    try {
+	        encoding = configuration.getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, (String)null);
+        } catch (CoreException e) {
+        }
+	    String defaultEncoding = getDefaultEncoding(configuration);
 		fDefaultEncodingButton.setText(MessageFormat.format(LaunchConfigurationsMessages.CommonTab_2, new Object[] { defaultEncoding }));
-		fDefaultEncodingButton.pack();
-		if (encoding != null) {
-			fAltEncodingButton.setSelection(true);
-			fDefaultEncodingButton.setSelection(false);
-			fEncodingCombo.setText(encoding);
-			fEncodingCombo.setEnabled(true);
-		} else {
-			fDefaultEncodingButton.setSelection(true);
-			fAltEncodingButton.setSelection(false);
-			fEncodingCombo.setEnabled(false);
-		}
+	    fDefaultEncodingButton.pack();
+        if (encoding != null) {
+            fAltEncodingButton.setSelection(true);
+            fDefaultEncodingButton.setSelection(false);
+            fEncodingCombo.setText(encoding);
+            fEncodingCombo.setEnabled(true);
+        } else {
+            fDefaultEncodingButton.setSelection(true);
+            fAltEncodingButton.setSelection(false);
+            fEncodingCombo.setEnabled(false);
+        }
 	}
 
 	/**
@@ -925,42 +949,42 @@
 		return validateLocalShared() && validateRedirectFile() && validateEncoding() && validateStdinFile();
 	}
 
-	/**
-	 * validates the encoding selection
-	 * @return true if the validate encoding is allowable, false otherwise
-	 */
-	private boolean validateEncoding() {
-		if (fAltEncodingButton.getSelection()) {
-			if (fEncodingCombo.getSelectionIndex() == -1) {
-				if (!isValidEncoding(fEncodingCombo.getText().trim())) {
-					setErrorMessage(LaunchConfigurationsMessages.CommonTab_15);
-					return false;
-				}
-			}
-		}
-		return true;
-	}
+    /**
+     * validates the encoding selection
+     * @return true if the validate encoding is allowable, false otherwise
+     */
+    private boolean validateEncoding() {
+        if (fAltEncodingButton.getSelection()) {
+            if (fEncodingCombo.getSelectionIndex() == -1) {
+            	if (!isValidEncoding(fEncodingCombo.getText().trim())) {
+                	setErrorMessage(LaunchConfigurationsMessages.CommonTab_15);
+                	return false;
+                }
+            }
+        }
+        return true;
+    }
 
-	/**
-	 * Validates if the redirect file is valid
-	 * @return true if the filename is not zero, false otherwise
-	 */
-	private boolean validateRedirectFile() {
-		if(fFileOutput.getSelection()) {
-			int len = fFileText.getText().trim().length();
-			if (len == 0) {
-				setErrorMessage(LaunchConfigurationsMessages.CommonTab_8);
-				return false;
-			}
-		}
-		return true;
-	}
+    /**
+     * Validates if the redirect file is valid
+     * @return true if the filename is not zero, false otherwise
+     */
+    private boolean validateRedirectFile() {
+        if(fFileOutput.getSelection()) {
+            int len = fFileText.getText().trim().length();
+            if (len == 0) {
+                setErrorMessage(LaunchConfigurationsMessages.CommonTab_8);
+                return false;
+            }
+        }
+        return true;
+    }
 
-	/**
-	 * validates the local shared config file location
-	 * @return true if the local shared file exists, false otherwise
-	 */
-	private boolean validateLocalShared() {
+    /**
+     * validates the local shared config file location
+     * @return true if the local shared file exists, false otherwise
+     */
+    private boolean validateLocalShared() {
 		if (isShared()) {
 			String path = fSharedLocationText.getText().trim();
 			IContainer container = getContainer(path);
@@ -1004,15 +1028,15 @@
 		setAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, configuration, fLaunchInBackgroundButton.getSelection(), true);
 		String encoding = null;
 		if(fAltEncodingButton.getSelection()) {
-			encoding = fEncodingCombo.getText().trim();
+		    encoding = fEncodingCombo.getText().trim();
 		}
 		configuration.setAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, encoding);
 		boolean captureOutput = false;
 		if (fConsoleOutput.getSelection()) {
-			captureOutput = true;
+		    captureOutput = true;
 			configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, (String) null);
 		} else {
-			configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, false);
+		    configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_CONSOLE, false);
 		}
 		if (fInputFileCheckButton.getSelection()) {
 			configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_STDIN_FILE, fInputFileLocationText.getText());
@@ -1020,22 +1044,29 @@
 			configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_STDIN_FILE, (String) null);
 		}
 		if (fFileOutput.getSelection()) {
-			captureOutput = true;
-			String file = fFileText.getText();
-			configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, file);
-			if(fAppend.getSelection()) {
-				configuration.setAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, true);
-			} else {
-				configuration.setAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, (String)null);
-			}
+		    captureOutput = true;
+		    String file = fFileText.getText();
+		    configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, file);
+		    if(fAppend.getSelection()) {
+		        configuration.setAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, true);
+		    } else {
+		        configuration.setAttribute(IDebugUIConstants.ATTR_APPEND_TO_FILE, (String)null);
+		    }
 		} else {
-			configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, (String)null);
+		    configuration.setAttribute(IDebugUIConstants.ATTR_CAPTURE_IN_FILE, (String)null);
+		}
+		if (fMergeOutput != null) {
+			if (fMergeOutput.getSelection()) {
+				configuration.setAttribute(IDebugUIConstants.ATTR_MERGE_OUTPUT, true);
+			} else {
+				configuration.setAttribute(IDebugUIConstants.ATTR_MERGE_OUTPUT, (String) null);
+			}
 		}
 
 		if (!captureOutput) {
-			configuration.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, false);
+		    configuration.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, false);
 		} else {
-			configuration.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, (String)null);
+		    configuration.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, (String)null);
 		}
 	}
 
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java
index 58be140..672ba0e 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2017 IBM Corporation and others.
+ *  Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  *  This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License 2.0
@@ -995,6 +995,18 @@
 	 */
 	String ATTR_APPEND_TO_FILE = PLUGIN_ID + ".ATTR_APPEND_TO_FILE"; //$NON-NLS-1$
 
+	/**
+	 * Launch configuration attribute - a boolean value indicating whether a
+	 * configuration should be launched with merged error and standard output.
+	 * Merging output can ensure the process output appears in console in same order
+	 * as the process produce it. On the other hand the error output can not be
+	 * colored different from standard output anymore. Default value is
+	 * <code>false</code>.
+	 *
+	 * @since 3.15
+	 */
+	String ATTR_MERGE_OUTPUT = PLUGIN_ID + ".ATTR_MERGE_OUTPUT"; //$NON-NLS-1$
+
 	// Extension points
 
 	/**