/*******************************************************************************
 * Copyright (c) 2000, 2019 Keith Seitz and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Keith Seitz (keiths@redhat.com) - initial implementation
 *     IBM Corporation - integration and code cleanup
 *     Jan Opacki (jan.opacki@gmail.com) bug 307139
 *     Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes
 *     Jens Reimann (jreimann@redhat.com) - add copy & paste support
 *     Andrew Obuchowicz (aobuchow@redhat.com) - Bug 548344
 *******************************************************************************/
package org.eclipse.debug.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.internal.ui.AbstractDebugCheckboxSelectionDialog;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.MultipleInputDialog;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.internal.ui.TextGetSetEditingSupport;
import org.eclipse.debug.internal.ui.launchConfigurations.EnvironmentVariable;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsMessages;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.jface.bindings.keys.SWTKeySupport;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.PlatformUI;

import com.ibm.icu.text.MessageFormat;

/**
 * Launch configuration tab for configuring the environment passed into
 * Runtime.exec(...) when a config is launched.
 * <p>
 * Clients may call {@link #setHelpContextId(String)} on this tab prior to
 * control creation to alter the default context help associated with this tab.
 * </p>
 * <p>
 * This class may be instantiated.
 * </p>
 *
 * @since 3.0
 * @noextend This class is not intended to be sub-classed by clients.
 */
public class EnvironmentTab extends AbstractLaunchConfigurationTab {

	protected TableViewer environmentTable;
	protected String[] envTableColumnHeaders = { LaunchConfigurationsMessages.EnvironmentTab_Variable_1,
			LaunchConfigurationsMessages.EnvironmentTab_Value_2, };
	private static final String NAME_LABEL = LaunchConfigurationsMessages.EnvironmentTab_8;
	private static final String VALUE_LABEL = LaunchConfigurationsMessages.EnvironmentTab_9;
	protected static final String P_VARIABLE = "variable"; //$NON-NLS-1$
	protected static final String P_VALUE = "value"; //$NON-NLS-1$
	protected Button envAddButton;
	protected Button envEditButton;
	protected Button envRemoveButton;
	/**
	 * @since 3.14
	 */
	protected Button envCopyButton;
	/**
	 * @since 3.14
	 */
	protected Button envPasteButton;
	protected Button appendEnvironment;
	protected Button replaceEnvironment;
	protected Button envSelectButton;

	private KeyStroke copyKeyStroke;
	private KeyStroke pasteKeyStroke;

	/**
	 * Content provider for the environment table
	 */
	protected class EnvironmentVariableContentProvider implements IStructuredContentProvider {
		@Override
		public Object[] getElements(Object inputElement) {
			EnvironmentVariable[] elements = new EnvironmentVariable[0];
			ILaunchConfiguration config = (ILaunchConfiguration) inputElement;
			Map<String, String> m;
			try {
				m = config.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<String, String>) null);
			} catch (CoreException e) {
				DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR,
						"Error reading configuration", e)); //$NON-NLS-1$
				return elements;
			}
			if (m != null && !m.isEmpty()) {
				elements = new EnvironmentVariable[m.size()];
				String[] varNames = new String[m.size()];
				m.keySet().toArray(varNames);
				for (int i = 0; i < m.size(); i++) {
					elements[i] = new EnvironmentVariable(varNames[i], m.get(varNames[i]));
				}
			}
			return elements;
		}

		@Override
		public void dispose() {
		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			if (newInput == null) {
				return;
			}
			if (viewer instanceof TableViewer) {
				TableViewer tableViewer = (TableViewer) viewer;
				if (tableViewer.getTable().isDisposed()) {
					return;
				}
				tableViewer.setComparator(new ViewerComparator() {
					@Override
					public int compare(Viewer iviewer, Object e1, Object e2) {
						if (e1 == null) {
							return -1;
						} else if (e2 == null) {
							return 1;
						} else {
							return ((EnvironmentVariable) e1).getName()
									.compareToIgnoreCase(((EnvironmentVariable) e2).getName());
						}
					}
				});
			}
		}
	}

	/**
	 * Label provider for the environment table
	 */
	public class EnvironmentVariableLabelProvider extends LabelProvider implements ITableLabelProvider {
		@Override
		public String getColumnText(Object element, int columnIndex) {
			String result = null;
			if (element != null) {
				EnvironmentVariable var = (EnvironmentVariable) element;
				switch (columnIndex) {
				case 0: // variable
					result = var.getName();
					break;
				case 1: // value
					result = var.getValue();
					break;
				default:
					break;
				}
			}
			return result;
		}

		@Override
		public Image getColumnImage(Object element, int columnIndex) {
			if (columnIndex == 0) {
				return DebugPluginImages.getImage(IDebugUIConstants.IMG_OBJS_ENV_VAR);
			}
			return null;
		}
	}

	/**
	 * Constructs a new tab with default context help.
	 */
	public EnvironmentTab() {
		super();
		setHelpContextId(IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_ENVIRONMENT_TAB);
		try {
			this.copyKeyStroke = KeyStroke.getInstance("M1+C"); //$NON-NLS-1$
		} catch (ParseException e) {
		}
		try {
			this.pasteKeyStroke = KeyStroke.getInstance("M1+V"); //$NON-NLS-1$
		} catch (ParseException e) {
		}
	}

	@Override
	public void createControl(Composite parent) {
		// Create main composite
		Composite mainComposite = SWTFactory.createComposite(parent, 2, 1, GridData.FILL_HORIZONTAL);
		setControl(mainComposite);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), getHelpContextId());

		createEnvironmentTable(mainComposite);
		createTableButtons(mainComposite);
		createAppendReplace(mainComposite);

		Dialog.applyDialogFont(mainComposite);
	}

	/**
	 * Creates and configures the widgets which allow the user to choose whether the
	 * specified environment should be appended to the native environment or if it
	 * should completely replace it.
	 *
	 * @param parent the composite in which the widgets should be created
	 */
	protected void createAppendReplace(Composite parent) {
		Composite comp = SWTFactory.createComposite(parent, 1, 2, GridData.FILL_HORIZONTAL);
		appendEnvironment = createRadioButton(comp, LaunchConfigurationsMessages.EnvironmentTab_16);
		appendEnvironment.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateLaunchConfigurationDialog();
			}
		});
		replaceEnvironment = createRadioButton(comp, LaunchConfigurationsMessages.EnvironmentTab_17);
	}

	/**
	 * Updates the enablement of the append/replace widgets. The widgets should
	 * disable when there are no environment variables specified.
	 */
	protected void updateAppendReplace() {
		boolean enable = environmentTable.getTable().getItemCount() > 0;
		appendEnvironment.setEnabled(enable);
		replaceEnvironment.setEnabled(enable);
	}

	/**
	 * Creates and configures the table that displayed the key/value pairs that
	 * comprise the environment.
	 *
	 * @param parent the composite in which the table should be created
	 */
	protected void createEnvironmentTable(Composite parent) {
		Font font = parent.getFont();
		// Create label, add it to the parent to align the right side buttons with the
		// top of the table
		SWTFactory.createLabel(parent, LaunchConfigurationsMessages.EnvironmentTab_Environment_variables_to_set__3, 2);
		// Create table composite
		Composite tableComposite = SWTFactory.createComposite(parent, font, 1, 1, GridData.FILL_BOTH, 0, 0);
		// Create table
		environmentTable = new TableViewer(tableComposite,
				SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
		Table table = environmentTable.getTable();
		table.setLayoutData(new GridData(GridData.FILL_BOTH));
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		table.setFont(font);
		environmentTable.setContentProvider(new EnvironmentVariableContentProvider());
		environmentTable.setLabelProvider(new EnvironmentVariableLabelProvider());
		environmentTable.setColumnProperties(new String[] { P_VARIABLE, P_VALUE });
		environmentTable.addSelectionChangedListener(this::handleTableSelectionChanged);

		// Setup right-click context menu
		Menu menuTable = new Menu(table);
		table.setMenu(menuTable);

		// Create add environment variable menu item
		MenuItem miAdd = new MenuItem(menuTable, SWT.NONE);
		miAdd.setText(LaunchConfigurationsMessages.EnvironmentTab_Add_4);
		miAdd.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvAddButtonSelected();
			}
		});

		// Create copy environment variable menu item
		MenuItem miCopy = new MenuItem(menuTable, SWT.NONE);
		miCopy.setText(LaunchConfigurationsMessages.EnvironmentTab_Copy);

		miCopy.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvCopyButtonSelected();
			}
		});

		// Create paste environment variable menu item
		MenuItem miPaste = new MenuItem(menuTable, SWT.NONE);
		miPaste.setText(LaunchConfigurationsMessages.EnvironmentTab_Paste);

		miPaste.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvPasteButtonSelected();
			}
		});

		// Create remove environment variable menu item
		MenuItem miRemove = new MenuItem(menuTable, SWT.NONE);
		miRemove.setText(LaunchConfigurationsMessages.EnvironmentTab_Remove_6);
		miRemove.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvRemoveButtonSelected();
			}
		});

		environmentTable.addSelectionChangedListener(event -> {
			IStructuredSelection selection = environmentTable.getStructuredSelection();
			if (selection.size() == 1) {
				miRemove.setText(LaunchConfigurationsMessages.EnvironmentTab_Remove_6);
			} else if (selection.size() > 1) {
				miRemove.setText(LaunchConfigurationsMessages.EnvironmentTab_Remove_All);
			}
		});

		// Disable certain context menu item's if no table item is selected
		table.addListener(SWT.MenuDetect, event -> {
			if (table.getSelectionCount() <= 0) {
				miRemove.setEnabled(false);
				miCopy.setEnabled(false);
			} else {
				miRemove.setEnabled(true);
				miCopy.setEnabled(true);
			}
		});

		// Setup and create Columns
		ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(environmentTable) {
			@Override
			protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
				return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
						|| event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION
						|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
			}

		};

		int feature = ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_HORIZONTAL
				| ColumnViewerEditor.KEYBOARD_ACTIVATION
				| ColumnViewerEditor.TABBING_CYCLE_IN_VIEWER;

		TableViewerEditor.create(environmentTable, actSupport, feature);

		// Setup environment variable name column
		final TableViewerColumn tcv1 = new TableViewerColumn(environmentTable, SWT.NONE, 0);
		tcv1.setLabelProvider(
				ColumnLabelProvider.createTextProvider(element -> ((EnvironmentVariable) element).getName()));

		TableColumn tc1 = tcv1.getColumn();
		tc1.setText(envTableColumnHeaders[0]);
		tcv1.setEditingSupport(new TextGetSetEditingSupport<>(tcv1.getViewer(), EnvironmentVariable::getName,
				(EnvironmentVariable envVar, String value) -> {
					// Trim environment variable names
					String newName = value.trim();
					if (newName != null && !newName.isEmpty()) {
						if (!newName.equals(envVar.getName())) {
							if (canRenameVariable(newName)) {
								envVar.setName(newName);
								updateAppendReplace();
								updateLaunchConfigurationDialog();
							}
						}
					}
				}));

		// Setup environment variable value column
		final TableViewerColumn tcv2 = new TableViewerColumn(environmentTable, SWT.NONE, 1);
		tcv2.setLabelProvider(
				ColumnLabelProvider.createTextProvider(element -> ((EnvironmentVariable) element).getValue()));

		TableColumn tc2 = tcv2.getColumn();
		tc2.setText(envTableColumnHeaders[1]);
		tcv2.setEditingSupport(
				new TextGetSetEditingSupport<>(tcv2.getViewer(), EnvironmentVariable::getValue, (envVar, value) -> {
					// Don't trim environment variable values
					envVar.setValue(value);
					updateAppendReplace();
					updateLaunchConfigurationDialog();
				}));

		// Create table column layout
		TableColumnLayout tableColumnLayout = new TableColumnLayout(true);
		PixelConverter pixelConverter = new PixelConverter(font);
		tableColumnLayout.setColumnData(tc1, new ColumnWeightData(1, pixelConverter.convertWidthInCharsToPixels(20)));
		tableColumnLayout.setColumnData(tc2, new ColumnWeightData(2, pixelConverter.convertWidthInCharsToPixels(20)));
		tableComposite.setLayout(tableColumnLayout);

		environmentTable.getTable().addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				KeyStroke current = computeKeyStroke(e);
				if (current.equals(copyKeyStroke)) {
					handleEnvCopyButtonSelected();
				} else if (current.equals(pasteKeyStroke)) {
					handleEnvPasteButtonSelected();
				}
			}

		});
	}

	/**
	 * Responds to a selection changed event in the environment table
	 *
	 * @param event the selection change event
	 */
	protected void handleTableSelectionChanged(SelectionChangedEvent event) {
		int size = event.getStructuredSelection().size();
		envEditButton.setEnabled(size == 1);
		envRemoveButton.setEnabled(size > 0);
		envCopyButton.setEnabled(size > 0);
	}

	/**
	 * Creates the add/edit/remove buttons for the environment table
	 *
	 * @param parent the composite in which the buttons should be created
	 */
	protected void createTableButtons(Composite parent) {
		// Create button composite
		Composite buttonComposite = SWTFactory.createComposite(parent, parent.getFont(), 1, 1,
				GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_END, 0, 0);

		// Create buttons
		envAddButton = createPushButton(buttonComposite, LaunchConfigurationsMessages.EnvironmentTab_Add_4, null);
		envAddButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvAddButtonSelected();
			}
		});
		envSelectButton = createPushButton(buttonComposite, LaunchConfigurationsMessages.EnvironmentTab_18, null);
		envSelectButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvSelectButtonSelected();
			}
		});
		envEditButton = createPushButton(buttonComposite, LaunchConfigurationsMessages.EnvironmentTab_Edit_5, null);
		envEditButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvEditButtonSelected();
			}
		});
		envEditButton.setEnabled(false);
		envRemoveButton = createPushButton(buttonComposite, LaunchConfigurationsMessages.EnvironmentTab_Remove_6, null);
		envRemoveButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvRemoveButtonSelected();
			}
		});
		envRemoveButton.setEnabled(false);
		envCopyButton = createPushButton(buttonComposite, LaunchConfigurationsMessages.EnvironmentTab_Copy, null);
		envCopyButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvCopyButtonSelected();
			}
		});
		envCopyButton.setEnabled(false);
		envPasteButton = createPushButton(buttonComposite, LaunchConfigurationsMessages.EnvironmentTab_Paste, null);
		envPasteButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				handleEnvPasteButtonSelected();
			}
		});
		envPasteButton.setEnabled(true);
	}

	/**
	 * Adds a new environment variable to the table.
	 */
	protected void handleEnvAddButtonSelected() {
		MultipleInputDialog dialog = new MultipleInputDialog(getShell(),
				LaunchConfigurationsMessages.EnvironmentTab_22);
		dialog.addTextField(NAME_LABEL, null, false);
		dialog.addVariablesField(VALUE_LABEL, null, true);

		if (dialog.open() != Window.OK) {
			return;
		}

		String name = dialog.getStringValue(NAME_LABEL);
		String value = dialog.getStringValue(VALUE_LABEL);

		if (name != null && value != null && name.length() > 0 && value.length() > 0) {
			// Trim the environment variable name but *NOT* the value
			addVariable(new EnvironmentVariable(name.trim(), value));
			updateAppendReplace();
		}
	}

	/**
	 * Returns whether the environment variable can be renamed to the given variable
	 * name. If the name is already used for another variable, the user decides with
	 * a dialog whether to overwrite the existing variable
	 *
	 * @param newVariableName the chosen name to give to the variable
	 * @return whether the new name should be used or not
	 */
	private boolean canRenameVariable(String newVariableName) {
		for (TableItem item : environmentTable.getTable().getItems()) {
			EnvironmentVariable existingVariable = (EnvironmentVariable) item.getData();
			if (existingVariable.getName().equals(newVariableName)) {

				boolean overWrite = MessageDialog.openQuestion(getShell(),
						LaunchConfigurationsMessages.EnvironmentTab_12,
						MessageFormat.format(LaunchConfigurationsMessages.EnvironmentTab_13,
								new Object[] { newVariableName }));
				if (!overWrite) {
					return false;
				}
				environmentTable.remove(existingVariable);
				return true;
			}
		}
		return true;
	}

	/**
	 * Attempts to add the given variable. Returns whether the variable
	 * was added or not (as when the user answers not to overwrite an
	 * existing variable).
	 * @param variable the variable to add
	 * @return whether the variable was added
	 */
	protected boolean addVariable(EnvironmentVariable variable) {
		String name = variable.getName();
		TableItem[] items = environmentTable.getTable().getItems();
		for (TableItem item : items) {
			EnvironmentVariable existingVariable = (EnvironmentVariable) item.getData();
			if (existingVariable.getName().equals(name)) {

				boolean overWrite = MessageDialog.openQuestion(getShell(),
						LaunchConfigurationsMessages.EnvironmentTab_12,
						MessageFormat.format(LaunchConfigurationsMessages.EnvironmentTab_13, new Object[] { name })); //
				if (!overWrite) {
					return false;
				}
				environmentTable.remove(existingVariable);
				break;
			}
		}
		environmentTable.add(variable);
		updateLaunchConfigurationDialog();
		return true;
	}

	/**
	 * Attempts to add the given variables. Returns the number of variables added
	 * (as when the user answers not to overwrite an existing variable).
	 *
	 * @param variables the variables to add
	 * @return the number of variables added
	 * @since 3.14
	 */
	protected int addVariables(List<EnvironmentVariable> variables) {
		if (variables.isEmpty()) {
			return 0;
		}

		List<EnvironmentVariable> remove = new LinkedList<>();
		List<EnvironmentVariable> conflicting = new LinkedList<>();
		Map<String, String> requested = variables.stream()
				.collect(Collectors.toMap(EnvironmentVariable::getName, EnvironmentVariable::getValue));

		for (TableItem item : environmentTable.getTable().getItems()) {
			EnvironmentVariable existingVariable = (EnvironmentVariable) item.getData();
			String name = existingVariable.getName();
			String currentValue = requested.get(name);
			if (currentValue != null) {
				remove.add(existingVariable);
				if (!currentValue.equals(existingVariable.getValue())) {
					conflicting.add(existingVariable);
				}
			}
		}

		if (!conflicting.isEmpty()) {
			String names = conflicting.stream().map(EnvironmentVariable::getName).collect(Collectors.joining(", ")); //$NON-NLS-1$
			boolean overWrite = MessageDialog.openQuestion(getShell(),
					LaunchConfigurationsMessages.EnvironmentTab_Paste_Overwrite_Title,
					MessageFormat.format(LaunchConfigurationsMessages.EnvironmentTab_Paste_Overwrite_Message,
							new Object[] { names })); //
			if (!overWrite) {
				return 0;
			}
		}

		remove.forEach(environmentTable::remove);
		variables.forEach(environmentTable::add);
		updateLaunchConfigurationDialog();

		return variables.size();
	}

	/**
	 * Displays a dialog that allows user to select native environment variables to
	 * add to the table.
	 */
	private void handleEnvSelectButtonSelected() {
		// get Environment Variables from the OS
		Map<String, EnvironmentVariable> envVariables = getNativeEnvironment();

		// get Environment Variables from the table
		TableItem[] items = environmentTable.getTable().getItems();
		for (TableItem item : items) {
			EnvironmentVariable var = (EnvironmentVariable) item.getData();
			envVariables.remove(var.getName());
		}

		NativeEnvironmentSelectionDialog dialog = new NativeEnvironmentSelectionDialog(getShell(), envVariables);
		dialog.setTitle(LaunchConfigurationsMessages.EnvironmentTab_20);

		int button = dialog.open();
		if (button == Window.OK) {
			Object[] selected = dialog.getResult();
			for (Object o : selected) {
				environmentTable.add(o);
			}
		}

		updateAppendReplace();
		updateLaunchConfigurationDialog();
	}

	/**
	 * Gets native environment variable from the LaunchManager. Creates
	 * EnvironmentVariable objects.
	 *
	 * @return Map of name - EnvironmentVariable pairs based on native environment.
	 */
	private Map<String, EnvironmentVariable> getNativeEnvironment() {
		Map<String, String> stringVars = DebugPlugin.getDefault().getLaunchManager()
				.getNativeEnvironmentCasePreserved();
		HashMap<String, EnvironmentVariable> vars = new HashMap<>();
		for (Entry<String, String> entry : stringVars.entrySet()) {
			vars.put(entry.getKey(), new EnvironmentVariable(entry.getKey(), entry.getValue()));
		}
		return vars;
	}

	/**
	 * Creates an editor for the value of the selected environment variable.
	 */
	private void handleEnvEditButtonSelected() {
		IStructuredSelection sel = environmentTable.getStructuredSelection();
		EnvironmentVariable var = (EnvironmentVariable) sel.getFirstElement();
		if (var == null) {
			return;
		}
		String originalName = var.getName();
		String value = var.getValue();
		MultipleInputDialog dialog = new MultipleInputDialog(getShell(),
				LaunchConfigurationsMessages.EnvironmentTab_11);
		dialog.addTextField(NAME_LABEL, originalName, false);
		if (value != null && value.contains(System.lineSeparator())) {
			dialog.addMultilinedVariablesField(VALUE_LABEL, value, true);
		} else {
			dialog.addVariablesField(VALUE_LABEL, value, true);
		}

		if (dialog.open() != Window.OK) {
			return;
		}

		String name = dialog.getStringValue(NAME_LABEL);
		value = dialog.getStringValue(VALUE_LABEL);
		if (!originalName.equals(name)) {
			// Trim the environment variable name but *NOT* the value
			if (addVariable(new EnvironmentVariable(name.trim(), value))) {
				environmentTable.remove(var);
			}
		} else {
			var.setValue(value);
			environmentTable.update(var, null);
			updateLaunchConfigurationDialog();
		}
	}

	/**
	 * Removes the selected environment variable from the table.
	 */
	private void handleEnvRemoveButtonSelected() {
		IStructuredSelection sel = environmentTable.getStructuredSelection();
		try {
			environmentTable.getControl().setRedraw(false);
			for (Iterator<?> i = sel.iterator(); i.hasNext();) {
				EnvironmentVariable var = (EnvironmentVariable) i.next();
				environmentTable.remove(var);
			}
		} finally {
			environmentTable.getControl().setRedraw(true);
		}
		updateAppendReplace();
		updateLaunchConfigurationDialog();
	}

	/**
	 * Copy the currently selected table entries to the clipboard.
	 */
	private void handleEnvCopyButtonSelected() {
		Iterable<?> iterable = () -> environmentTable.getStructuredSelection().iterator();
		String data = StreamSupport.stream(iterable.spliterator(), false).filter(o -> o instanceof EnvironmentVariable)
				.map(EnvironmentVariable.class::cast).map(var -> String.format("%s=%s", var.getName(), var.getValue())) //$NON-NLS-1$
				.collect(Collectors.joining(System.lineSeparator()));

		Clipboard clipboard = new Clipboard(getShell().getDisplay());
		try {
			clipboard.setContents(new Object[] { data }, new Transfer[] { TextTransfer.getInstance() });
		} finally {
			clipboard.dispose();
		}
	}

	/**
	 * Extract the content from the clipboard and add the new content.
	 */
	private void handleEnvPasteButtonSelected() {
		Clipboard clipboard = new Clipboard(getShell().getDisplay());
		try {
			List<EnvironmentVariable> variables = convertEnvironmentVariablesFromData(
					clipboard.getContents(TextTransfer.getInstance()));
			addVariables(variables);
			updateAppendReplace();
		} finally {
			clipboard.dispose();
		}
	}

	/**
	 * Convert the clipboard data to a list of {@link EnvironmentVariable}s. <br>
	 * Only entries containing an equals sign ({@code =} will be considered.
	 *
	 * @param data The clipboard data. May be {@code null}, which will result in an
	 *             empty list.
	 * @return The resulting and valid {@link EnvironmentVariable}s in an
	 *         unmodifiable list.
	 */
	private static List<EnvironmentVariable> convertEnvironmentVariablesFromData(Object data) {
		if (!(data instanceof String)) {
			return Collections.emptyList();
		}

		String entries[] = ((String) data).split("\\R"); //$NON-NLS-1$
		List<EnvironmentVariable> result = new ArrayList<>(entries.length);
		for (String entry : entries) {
			int idx = entry.indexOf('=');
			if (idx < 1) {
				continue;
			}
			// the name is trimmed ...
			String name = entry.substring(0, idx).trim();
			// .. but the value is *not* trimmed
			String value = entry.substring(idx + 1);
			result.add(new EnvironmentVariable(name, value));
		}
		return Collections.unmodifiableList(result);
	}

	/**
	 * Updates the environment table for the given launch configuration
	 *
	 * @param configuration the configuration to use as input for the backing table
	 */
	protected void updateEnvironment(ILaunchConfiguration configuration) {
		environmentTable.setInput(configuration);
	}

	@Override
	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
		configuration.removeAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES);
	}

	@Override
	public void initializeFrom(ILaunchConfiguration configuration) {
		boolean append = true;
		try {
			append = configuration.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
		} catch (CoreException e) {
			DebugUIPlugin.log(e.getStatus());
		}
		if (append) {
			appendEnvironment.setSelection(true);
			replaceEnvironment.setSelection(false);
		} else {
			replaceEnvironment.setSelection(true);
			appendEnvironment.setSelection(false);
		}
		updateEnvironment(configuration);
		updateAppendReplace();
	}

	/**
	 * Stores the environment in the given configuration
	 *
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
	 */
	@Override
	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
		// Convert the table's items into a Map so that this can be saved in the
		// configuration's attributes.
		TableItem[] items = environmentTable.getTable().getItems();
		Map<String, String> map = new HashMap<>(items.length);
		for (TableItem item : items) {
			EnvironmentVariable var = (EnvironmentVariable) item.getData();
			map.put(var.getName(), var.getValue());
		}
		if (map.isEmpty()) {
			configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, (Map<String, String>) null);
		} else {
			configuration.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, map);
		}

		if (appendEnvironment.getSelection()) {
			ILaunchConfiguration orig = configuration.getOriginal();
			boolean hasTrueValue = false;
			if (orig != null) {
				try {
					hasTrueValue = orig.hasAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES)
							&& orig.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
				} catch (CoreException e) {
					DebugUIPlugin.log(e.getStatus());
				}
			}
			if (hasTrueValue) {
				configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
			} else {
				configuration.removeAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES);
			}
		} else {
			configuration.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false);
		}
	}

	@Override
	public String getName() {
		return LaunchConfigurationsMessages.EnvironmentTab_Environment_7;
	}

	/**
	 * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getId()
	 *
	 * @since 3.3
	 */
	@Override
	public String getId() {
		return "org.eclipse.debug.ui.environmentTab"; //$NON-NLS-1$
	}

	@Override
	public Image getImage() {
		return DebugPluginImages.getImage(IDebugUIConstants.IMG_OBJS_ENVIRONMENT);
	}

	@Override
	public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
		// do nothing when activated
	}

	@Override
	public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) {
		// do nothing when deactivated
	}

	/**
	 * @since 3.13
	 */
	@Override
	protected void initializeAttributes() {
		super.initializeAttributes();
		getAttributesLabelsForPrototype().put(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES,
				LaunchConfigurationsMessages.EnvironmentTab_AttributeLabel_AppendEnvironmentVariables);
		getAttributesLabelsForPrototype().put(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,
				LaunchConfigurationsMessages.EnvironmentTab_AttributeLabel_EnvironmentVariables);
	}

	private KeyStroke computeKeyStroke(KeyEvent e) {
		int accelerator = SWTKeySupport.convertEventToUnmodifiedAccelerator(e);
		return SWTKeySupport.convertAcceleratorToKeyStroke(accelerator);
	}

	/**
	 * This dialog allows users to select one or more known native environment
	 * variables from a list.
	 */
	private class NativeEnvironmentSelectionDialog extends AbstractDebugCheckboxSelectionDialog {

		private Object fInput;

		public NativeEnvironmentSelectionDialog(Shell parentShell, Object input) {
			super(parentShell);
			fInput = input;
			setShellStyle(getShellStyle() | SWT.RESIZE);
			setShowSelectAllButtons(true);
		}

		@Override
		protected String getDialogSettingsId() {
			return IDebugUIConstants.PLUGIN_ID + ".ENVIRONMENT_TAB.NATIVE_ENVIROMENT_DIALOG"; //$NON-NLS-1$
		}

		@Override
		protected String getHelpContextId() {
			return IDebugHelpContextIds.SELECT_NATIVE_ENVIRONMENT_DIALOG;
		}

		@Override
		protected Object getViewerInput() {
			return fInput;
		}

		@Override
		protected String getViewerLabel() {
			return LaunchConfigurationsMessages.EnvironmentTab_19;
		}

		@Override
		protected IBaseLabelProvider getLabelProvider() {
			return new ILabelProvider() {
				@Override
				public Image getImage(Object element) {
					return DebugPluginImages.getImage(IDebugUIConstants.IMG_OBJS_ENVIRONMENT);
				}

				@Override
				public String getText(Object element) {
					EnvironmentVariable var = (EnvironmentVariable) element;
					return MessageFormat.format(LaunchConfigurationsMessages.EnvironmentTab_7,
							new Object[] { var.getName(), var.getValue() });
				}

				@Override
				public void addListener(ILabelProviderListener listener) {
				}

				@Override
				public void dispose() {
				}

				@Override
				public boolean isLabelProperty(Object element, String property) {
					return false;
				}

				@Override
				public void removeListener(ILabelProviderListener listener) {
				}
			};
		}

		@Override
		protected IContentProvider getContentProvider() {
			return new IStructuredContentProvider() {
				@Override
				public Object[] getElements(Object inputElement) {
					EnvironmentVariable[] elements = null;
					if (inputElement instanceof HashMap) {
						Comparator<Object> comparator = (o1, o2) -> {
							String s1 = (String) o1;
							String s2 = (String) o2;
							return s1.compareTo(s2);
						};
						TreeMap<Object, Object> envVars = new TreeMap<>(comparator);
						envVars.putAll((Map<?, ?>) inputElement);
						elements = new EnvironmentVariable[envVars.size()];
						int index = 0;
						for (Iterator<Object> iterator = envVars.keySet().iterator(); iterator.hasNext(); index++) {
							Object key = iterator.next();
							elements[index] = (EnvironmentVariable) envVars.get(key);
						}
					}
					return elements;
				}

				@Override
				public void dispose() {
				}

				@Override
				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
				}
			};
		}
	}
}
