/*******************************************************************************
 * Copyright (c) 2000, 2021 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes
 *******************************************************************************/
package org.eclipse.debug.tests.launching;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileSystem;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationListener;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.internal.core.LaunchConfiguration;
import org.eclipse.debug.internal.core.LaunchManager;
import org.eclipse.debug.tests.TestsPlugin;
import org.eclipse.debug.tests.console.MockProcess;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.junit.Test;
import org.osgi.framework.Bundle;

/**
 * Tests for launch configurations
 */
@SuppressWarnings("deprecation")
public class LaunchConfigurationTests extends AbstractLaunchTest implements ILaunchConfigurationListener {

	/**
	 * Identifier of test launch configuration type extension
	 */
	public static final String ID_TEST_LAUNCH_TYPE = "org.eclipse.debug.tests.launch.type"; //$NON-NLS-1$

	/**
	 * The from/to handles during rename operations
	 */
	protected ILaunchConfiguration fFrom;
	protected ILaunchConfiguration fTo;

	protected Object fLock = new Object();
	protected ILaunchConfiguration fAdded;
	protected ILaunchConfiguration fRemoved;

	/**
	 * Class to hold resource description infos
	 * @since 3.9.0
	 */
	static class ResourceItem {
		public ResourceItem(String path, Integer type) {
			this.path = path;
			this.type = type;
		}
		String path;
		Integer type;
	}

	static class Listener implements ILaunchConfigurationListener {

		private final List<ILaunchConfiguration> addedList = new ArrayList<>();
		private final List<ILaunchConfiguration> removedList = new ArrayList<>();
		private final List<ILaunchConfiguration> changedList = new ArrayList<>();

		@Override
		public void launchConfigurationAdded(ILaunchConfiguration configuration) {
			addedList.add(configuration);
		}

		@Override
		public void launchConfigurationChanged(ILaunchConfiguration configuration) {
			changedList.add(configuration);
		}

		@Override
		public void launchConfigurationRemoved(ILaunchConfiguration configuration) {
			removedList.add(configuration);
		}

		public List<ILaunchConfiguration> getAdded() {
			return addedList;
		}

		public List<ILaunchConfiguration> getChanged() {
			return changedList;
		}

		public List<ILaunchConfiguration> getRemoved() {
			return removedList;
		}

	}

	/**
	 * Returns the given input stream's contents as a character array.
	 * If a length is specified (i.e. if length != -1), this represents the number of bytes in the stream.
	 * Note the specified stream is not closed in this method
	 * @param stream the stream to get convert to the char array
	 * @return the given input stream's contents as a character array.
	 * @throws IOException if a problem occurred reading the stream.
	 */
	public static char[] getInputStreamAsCharArray(InputStream stream) throws IOException {
		Charset charset = StandardCharsets.UTF_8;
		CharsetDecoder charsetDecoder = charset.newDecoder();
		charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);
		byte[] contents = getInputStreamAsByteArray(stream, -1);
		ByteBuffer byteBuffer = ByteBuffer.allocate(contents.length);
		byteBuffer.put(contents);
		byteBuffer.flip();
		return charsetDecoder.decode(byteBuffer).array();
	}

	/**
	 * Returns the given input stream as a byte array
	 * @param stream the stream to get as a byte array
	 * @param length the length to read from the stream or -1 for unknown
	 * @return the given input stream as a byte array
	 * @throws IOException
	 */
	public static byte[] getInputStreamAsByteArray(InputStream stream, int length) throws IOException {
		byte[] contents;
		if (length == -1) {
			contents = new byte[0];
			int contentsLength = 0;
			int amountRead = -1;
			do {
				// read at least 8K
				int amountRequested = Math.max(stream.available(), 8192);
				// resize contents if needed
				if (contentsLength + amountRequested > contents.length) {
					System.arraycopy(contents,
							0,
							contents = new byte[contentsLength + amountRequested],
							0,
							contentsLength);
				}
				// read as many bytes as possible
				amountRead = stream.read(contents, contentsLength, amountRequested);
				if (amountRead > 0) {
					// remember length of contents
					contentsLength += amountRead;
				}
			} while (amountRead != -1);
			// resize contents if necessary
			if (contentsLength < contents.length) {
				System.arraycopy(contents, 0, contents = new byte[contentsLength], 0, contentsLength);
			}
		} else {
			contents = new byte[length];
			int len = 0;
			int readSize = 0;
			while ((readSize != -1) && (len != length)) {
				// See PR 1FMS89U
				// We record first the read size. In this case length is the actual
				// read size.
				len += readSize;
				readSize = stream.read(contents, len, length - len);
			}
		}
		return contents;
	}

	/**
	 * Returns a scratch project for launch configurations
	 *
	 * @return
	 */
	protected IProject getProject() throws CoreException {
		return TestsPlugin.createProject("LaunchConfigurationTests"); //$NON-NLS-1$
	}

	/**
	 * Creates and returns a new launch config the given name, local
	 * or shared, with 4 attributes:
	 *  - String1 = "String1"
	 *  - Int1 = 1
	 *  - Boolean1 = true
	 *  - Boolean2 = false
	 */
	protected ILaunchConfigurationWorkingCopy newConfiguration(IContainer container, String name) throws CoreException {
		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(ID_TEST_LAUNCH_TYPE);
		assertTrue("Should support debug mode", type.supportsMode(ILaunchManager.DEBUG_MODE)); //$NON-NLS-1$
		assertTrue("Should support run mode", type.supportsMode(ILaunchManager.RUN_MODE)); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy wc = type.newInstance(container, name);
		wc.setAttribute("String1", "String1"); //$NON-NLS-1$ //$NON-NLS-2$
		wc.setAttribute("Int1", 1); //$NON-NLS-1$
		wc.setAttribute("Boolean1", true); //$NON-NLS-1$
		wc.setAttribute("Boolean2", false); //$NON-NLS-1$
		assertTrue("Should need saving", wc.isDirty()); //$NON-NLS-1$
		return wc;
	}

	/**
	 * Creates and returns a new launch configuration with the given name, local
	 * or shared, with no attributes
	 */
	protected ILaunchConfigurationWorkingCopy newEmptyConfiguration(IContainer container, String name) throws CoreException {
		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(ID_TEST_LAUNCH_TYPE);
		ILaunchConfigurationWorkingCopy wc = type.newInstance(container, name);
		assertEquals("Should have no attributes", 0, wc.getAttributes().size()); //$NON-NLS-1$
		return wc;
	}

	/**
	 * Creates and returns a new launch config prototype with the given name, local
	 * or shared, with 4 attributes:
	 *  - String1 = "String1"
	 *  - Int1 = 1
	 *  - Boolean1 = true
	 *  - Boolean2 = false
	 */
	protected ILaunchConfigurationWorkingCopy newPrototype(IContainer container, String name) throws CoreException {
		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(ID_TEST_LAUNCH_TYPE);
		assertTrue("Should support debug mode", type.supportsMode(ILaunchManager.DEBUG_MODE)); //$NON-NLS-1$
		assertTrue("Should support run mode", type.supportsMode(ILaunchManager.RUN_MODE)); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy wc = type.newPrototypeInstance(container, name);
		wc.setAttribute("String1", "String1"); //$NON-NLS-1$ //$NON-NLS-2$
		wc.setAttribute("Int1", 1); //$NON-NLS-1$
		wc.setAttribute("Boolean1", true); //$NON-NLS-1$
		wc.setAttribute("Boolean2", false); //$NON-NLS-1$
		assertTrue("Should need saving", wc.isDirty()); //$NON-NLS-1$
		return wc;
	}

	/**
	 * Creates and returns a new launch configuration prototype with the given name, local
	 * or shared, with no attributes
	 */
	protected ILaunchConfigurationWorkingCopy newEmptyPrototype(IContainer container, String name) throws CoreException {
		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(ID_TEST_LAUNCH_TYPE);
		ILaunchConfigurationWorkingCopy wc = type.newPrototypeInstance(container, name);
		assertEquals("Should have no attributes", 0, wc.getAttributes().size()); //$NON-NLS-1$
		return wc;
	}

	/**
	 * Returns whether the given handle is contained in the specified
	 * array of handles.
	 */
	protected boolean existsIn(ILaunchConfiguration[] configs, ILaunchConfiguration config) {
		for (ILaunchConfiguration c : configs) {
			if (c.equals(config)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Creates a local working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testCreateLocalConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config1"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertEquals("String1 should be String1", handle.getAttribute("String1", "Missing"), "String1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertEquals("Int1 should be 1", handle.getAttribute("Int1", 0), 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));  //$NON-NLS-1$//$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));  //$NON-NLS-1$//$NON-NLS-2$

		// ensure new handle is the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should exist in project index", existsIn(configs, handle)); //$NON-NLS-1$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Creates a local working copy configuration and tests its name.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testLocalName() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "localName"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertEquals("Wrong name", handle.getName(), "localName"); //$NON-NLS-1$ //$NON-NLS-2$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Creates a shared working copy configuration and tests is name.
	 */
	@Test
	public void testSharedName() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(getProject(), "sharedName"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertEquals("Wrong name", handle.getName(), "sharedName"); //$NON-NLS-1$ //$NON-NLS-2$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Ensures that a launch configuration returns a complete attribute map
	 *
	 * @throws CoreException
	 */
	@Test
	public void testGetAttributes() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config1"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		Map<?, ?> attributes = handle.getAttributes();
		// retrieve attributes
		assertEquals("String1 should be String1", "String1", attributes.get("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertEquals("Int1 should be 1", Integer.valueOf(1), attributes.get("Int1")); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Boolean1 should be true", Boolean.TRUE, attributes.get("Boolean1")); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Boolean2 should be false", Boolean.FALSE, attributes.get("Boolean2")); //$NON-NLS-1$ //$NON-NLS-2$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Ensures that set attributes works
	 *
	 * @throws CoreException
	 */
	@Test
	public void testSetAttributes() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config1"); //$NON-NLS-1$
		Map<String, Object> map = new HashMap<>();
		map.put("ATTR1", "ONE"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("ATTR2", "TWO"); //$NON-NLS-1$ //$NON-NLS-2$
		wc.setAttributes(map);
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		Map<?, ?> attributes = handle.getAttributes();
		assertEquals("should have two attributes", 2, attributes.size()); //$NON-NLS-1$
		// retrieve attributes
		assertEquals("ATTR1 should be ONE", "ONE", attributes.get("ATTR1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		assertEquals("ATTR2 should be TWO", "TWO", attributes.get("ATTR2")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Ensures that set attributes to <code>null</code> works
	 *
	 * @throws CoreException
	 */
	@Test
	public void testSetNullAttributes() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config1"); //$NON-NLS-1$
		wc.setAttributes(null);
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		Map<?, ?> attributes = handle.getAttributes();
		assertEquals("should have no attributes", 0, attributes.size()); //$NON-NLS-1$
		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Creates a local working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes. Copy the
	 * configuration and ensure the original still exists.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testLocalCopy() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "configToCopy"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should exist in project index", existsIn(configs, handle)); //$NON-NLS-1$

		ILaunchConfigurationWorkingCopy softCopy = handle.copy("CopyOf" + handle.getName()); //$NON-NLS-1$
		assertNull("Original in copy should be null", softCopy.getOriginal()); //$NON-NLS-1$
		ILaunchConfiguration hardCopy = softCopy.doSave();

		// retrieve attributes
		assertTrue("String1 should be String1", hardCopy.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", hardCopy.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", hardCopy.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !hardCopy.getAttribute("Boolean2", true));		  //$NON-NLS-1$ //$NON-NLS-2$

		assertTrue("Original should still exist", handle.exists()); //$NON-NLS-1$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
		hardCopy.delete();
		assertTrue("Config should not exist after deletion", !hardCopy.exists());		 		  //$NON-NLS-1$
	}

	/**
	 * Create a config and save it twice, ensuring it only ends up in the index
	 * once.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testDoubleSave() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "configDoubleSave"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should exist in project index", existsIn(configs, handle)); //$NON-NLS-1$

		String name = wc.getName();
		wc.rename("newName"); //$NON-NLS-1$
		wc.rename(name);
		assertTrue("Should be dirty", wc.isDirty()); //$NON-NLS-1$
		wc.doSave();

		ILaunchConfiguration[] newConfigs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Should be the same number of configs", newConfigs.length == configs.length); //$NON-NLS-1$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$

	}

	/**
	 * Creates a local working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes. Deletes the
	 * configuration and ensures it no longer exists.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testDeleteLocalConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config2delete"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		File file = wc.getLocation().toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// delete
		handle.delete();
		assertTrue("Config should no longer exist", !handle.exists()); //$NON-NLS-1$

		// ensure handle is not in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should not exist in project index", !existsIn(configs, handle));		  //$NON-NLS-1$
	}

	/**
	 * Creates a local working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes. Renames the
	 * configuration and ensures it's old config no longer exists, and that
	 * attributes are retrievable from the new (renamed) config.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testRenameLocalConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config2rename"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// rename
		wc = handle.getWorkingCopy();
		wc.rename("config-2-rename"); //$NON-NLS-1$
		addConfigListener();
		ILaunchConfiguration newHandle = wc.doSave();
		removeConfigListener();
		assertTrue("Config should no longer exist", !handle.exists()); //$NON-NLS-1$
		assertEquals("From should be original", handle, fFrom); //$NON-NLS-1$
		assertEquals("To should be new handle", newHandle, fTo); //$NON-NLS-1$

		// retrieve new attributes
		assertTrue("String1 should be String1", newHandle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", newHandle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", newHandle.getAttribute("Boolean1", false));  //$NON-NLS-1$//$NON-NLS-2$
		assertTrue("Boolean2 should be false", !newHandle.getAttribute("Boolean2", true));		  //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Renamed configuration should exist in project index", existsIn(configs, newHandle));		  //$NON-NLS-1$
		assertTrue("Original configuration should NOT exist in project index", !existsIn(configs, handle));	 //$NON-NLS-1$

		// cleanup
		newHandle.delete();
		assertTrue("Config should not exist after deletion", !newHandle.exists());		 	  //$NON-NLS-1$
	}

	/**
	 * Moves a local configuration to a shared location
	 *
	 * @throws CoreException
	 */
	@Test
	public void testMoveLocalToSharedConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config2share"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// move
		wc = handle.getWorkingCopy();
		wc.setContainer(getProject());
		addConfigListener();
		ILaunchConfiguration newHandle = wc.doSave();
		removeConfigListener();
		assertTrue("Config should no longer exist", !handle.exists()); //$NON-NLS-1$
		assertEquals("From should be original", handle, fFrom); //$NON-NLS-1$
		assertEquals("To should be new handle", newHandle, fTo); //$NON-NLS-1$

		// retrieve new attributes
		assertTrue("String1 should be String1", newHandle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", newHandle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", newHandle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !newHandle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Renamed configuration should exist in project index", existsIn(configs, newHandle)); //$NON-NLS-1$
		assertTrue("Original configuration should NOT exist in project index", !existsIn(configs, handle)); //$NON-NLS-1$

		// cleanup
		newHandle.delete();
		assertTrue("Config should not exist after deletion", !newHandle.exists()); //$NON-NLS-1$
	}

	/**
	 * Moves a local configuration to a shared location
	 *
	 * @throws CoreException
	 */
	@Test
	public void testMoveSharedToLocalConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(getProject(), "config2local"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// move
		wc = handle.getWorkingCopy();
		wc.setContainer(null);
		addConfigListener();
		ILaunchConfiguration newHandle = wc.doSave();
		removeConfigListener();
		assertTrue("Config should no longer exist", !handle.exists()); //$NON-NLS-1$
		assertEquals("From should be original", handle, fFrom); //$NON-NLS-1$
		assertEquals("To should be new handle", newHandle, fTo); //$NON-NLS-1$

		// retrieve new attributes
		assertTrue("String1 should be String1", newHandle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", newHandle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", newHandle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !newHandle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Renamed configuration should exist in project index", existsIn(configs, newHandle)); //$NON-NLS-1$
		assertTrue("Original configuration should NOT exist in project index", !existsIn(configs, handle)); //$NON-NLS-1$

		// cleanup
		newHandle.delete();
		assertTrue("Config should not exist after deletion", !newHandle.exists()); //$NON-NLS-1$
	}

	/**
	 * Creates a shared working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testCreateSharedConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(getProject(), "config2"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should exist in project index", existsIn(configs, handle));  //$NON-NLS-1$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Creates a shared working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes. Copies the
	 * configuration and ensures the original still exists.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testSharedCopy() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(getProject(), "config2Copy"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should exist in project index", existsIn(configs, handle));  //$NON-NLS-1$

		// copy
		ILaunchConfigurationWorkingCopy softCopy = handle.copy("CopyOf" + handle.getName()); //$NON-NLS-1$
		ILaunchConfiguration hardCopy = softCopy.doSave();

		// retrieve attributes
		assertTrue("String1 should be String1", hardCopy.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", hardCopy.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", hardCopy.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !hardCopy.getAttribute("Boolean2", true));		  //$NON-NLS-1$ //$NON-NLS-2$

		assertTrue("Original should still exist", handle.exists()); //$NON-NLS-1$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
		hardCopy.delete();
		assertTrue("Config should not exist after deletion", !hardCopy.exists());		 		 		  //$NON-NLS-1$
	}


	/**
	 * Creates a shared working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes. Deletes the
	 * configuration and ensures it no longer exists.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testDeleteSharedConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(getProject(), "shared2delete"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// delete
		handle.delete();
		assertTrue("Config should no longer exist", !handle.exists()); //$NON-NLS-1$

		// ensure handle is not in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should not exist in project index", !existsIn(configs, handle));		  //$NON-NLS-1$
	}

	/**
	 * Creates a shared working copy configuration, sets some attributes, and
	 * saves the working copy, and retrieves the attributes. Renames the
	 * configuration and ensures it's old config no longer exists, and that
	 * attributes are retrievable from the new (renamed) config.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testRenameSharedConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(getProject(), "shared2rename"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// rename
		wc = handle.getWorkingCopy();
		wc.rename("shared-2-rename"); //$NON-NLS-1$
		addConfigListener();
		ILaunchConfiguration newHandle = wc.doSave();
		removeConfigListener();
		assertTrue("Config should no longer exist", !handle.exists()); //$NON-NLS-1$
		assertEquals("From should be original", handle, fFrom); //$NON-NLS-1$
		assertEquals("To should be new handle", newHandle, fTo);		  //$NON-NLS-1$

		// retrieve new attributes
		assertTrue("String1 should be String1", newHandle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", newHandle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", newHandle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !newHandle.getAttribute("Boolean2", true));		  //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is in the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Renamed configuration should exist in project index", existsIn(configs, newHandle));		  //$NON-NLS-1$
		assertTrue("Original configuration should NOT exist in project index", !existsIn(configs, handle));		  //$NON-NLS-1$

		// cleanup
		newHandle.delete();
		assertTrue("Config should not exist after deletion", !newHandle.exists());		  //$NON-NLS-1$
	}

	/**
	 * Closes all editors in the active workbench page.
	 */
	protected void closeAllEditors() {
		IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		activeWorkbenchWindow.getActivePage().closeAllEditors(false);
	}

	/**
	 * Creates a few configs, closes the project and re-opens the project to
	 * ensure the config index is persisted properly
	 *
	 * @throws CoreException
	 */
	@Test
	public void testPersistIndex() throws CoreException {
		// close all editors before closing project: @see bug 204023
		closeAllEditors();

		ILaunchConfigurationWorkingCopy wc1 = newConfiguration(null, "persist1local"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy wc2 = newConfiguration(getProject(), "persist2shared"); //$NON-NLS-1$
		ILaunchConfiguration lc1 = wc1.doSave();
		ILaunchConfiguration lc2 = wc2.doSave();

		IProject project = getProject();
		ILaunchConfiguration[] before = getLaunchManager().getLaunchConfigurations();
		assertTrue("config should be in index", existsIn(before, lc1)); //$NON-NLS-1$
		assertTrue("config should be in index", existsIn(before, lc2)); //$NON-NLS-1$

		project.close(null);
		ILaunchConfiguration[] during = getLaunchManager().getLaunchConfigurations();
		boolean local = true;
		for (ILaunchConfiguration d : during) {
			// must be local, or not from the closed project
			local = local && (d.isLocal() || !d.getFile().getProject().equals(project));
		}
		project.open(null);
		assertTrue("Should only be local configs when closed", local); //$NON-NLS-1$
		ILaunchConfiguration[] after = getLaunchManager().getLaunchConfigurations();
		assertTrue("Should be same number of configs after openning", after.length == before.length); //$NON-NLS-1$
		for (ILaunchConfiguration b : before) {
			assertTrue("Config should exist after openning", existsIn(after, b)); //$NON-NLS-1$
		}

		// cleanup
		lc1.delete();
		assertTrue("Config should not exist after deletion", !lc1.exists()); //$NON-NLS-1$
		lc2.delete();
		assertTrue("Config should not exist after deletion", !lc2.exists());		  //$NON-NLS-1$


	}


	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationAdded(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationAdded(ILaunchConfiguration configuration) {
		fFrom = getLaunchManager().getMovedFrom(configuration);
		synchronized (fLock) {
			fAdded = configuration;
			fLock.notifyAll();
		}
	}

	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationChanged(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationChanged(ILaunchConfiguration configuration) {
	}

	/**
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationRemoved(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationRemoved(ILaunchConfiguration configuration) {
		fTo = getLaunchManager().getMovedTo(configuration);
		synchronized (fLock) {
			fRemoved = configuration;
			fLock.notifyAll();
		}
	}

	protected void addConfigListener() {
		getLaunchManager().addLaunchConfigurationListener(this);
	}

	protected void removeConfigListener() {
		getLaunchManager().removeLaunchConfigurationListener(this);
	}

	/**
	 * Ensures that a removal notification is sent for a shared config in a
	 * project that is deleted.
	 *
	 * @throws Exception
	 */
	@Test
	public void testDeleteProjectWithSharedConfig() throws Exception {
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("DeleteSharedConfig"); //$NON-NLS-1$
		try {
			assertFalse("project should not exist yet", project.exists()); //$NON-NLS-1$
			project.create(null);
			assertTrue("project should now exist", project.exists()); //$NON-NLS-1$
			project.open(null);
			assertTrue("project should be open", project.isOpen()); //$NON-NLS-1$
			ILaunchConfigurationWorkingCopy wc = newConfiguration(project, "ToBeDeleted"); //$NON-NLS-1$

			addConfigListener();
			ILaunchConfiguration configuration = wc.doSave();
			assertEquals(configuration, fAdded);

			synchronized (fLock) {
				fRemoved = null;
				project.delete(true, false, null);
				if (fRemoved == null) {
					fLock.wait(10000);
				}
			}
			assertEquals(configuration, fRemoved);
		} finally {
			if (project.exists()) {
				project.delete(true, false, null);
			}
			removeConfigListener();
		}
	}

	/**
	 * Tests a nested working copy.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testNestedWorkingCopyLocalConfiguration() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config123"); //$NON-NLS-1$
		IPath location = wc.getLocation();
		ILaunchConfiguration handle = wc.doSave();
		File file = location.toFile();
		assertTrue("Configuration file should exist", file.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertEquals("String1 should be String1", handle.getAttribute("String1", "Missing"), "String1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertEquals("Int1 should be 1", handle.getAttribute("Int1", 0), 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// ensure new handle is the index
		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
		assertTrue("Configuration should exist in project index", existsIn(configs, handle)); //$NON-NLS-1$

		// get a working copy
		wc = handle.getWorkingCopy();
		ILaunchConfigurationWorkingCopy nested = wc.getWorkingCopy();

		// verify nested is same as original
		assertEquals("String1 should be String1", nested.getAttribute("String1", "Missing"), "String1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertEquals("Int1 should be 1", nested.getAttribute("Int1", 0), 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", nested.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !nested.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// change an attribute in the nested working copy
		nested.setAttribute("String1", "StringOne"); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Wrong attribute value", nested.getAttribute("String1", "Missing"), "StringOne"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertEquals("Wrong attribute value", wc.getAttribute("String1", "Missing"), "String1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertEquals("Wrong attribute value", handle.getAttribute("String1", "Missing"), "String1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$

		// save back to parent
		ILaunchConfigurationWorkingCopy parent = nested.getParent();
		assertEquals("Wrong parent", wc, parent); //$NON-NLS-1$
		assertNull("Should have no parent", wc.getParent()); //$NON-NLS-1$
		nested.doSave();
		assertEquals("Wrong attribute value", wc.getAttribute("String1", "Missing"), "StringOne");  //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
		assertEquals("Wrong attribute value", handle.getAttribute("String1", "Missing"), "String1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$

		// check originals
		assertEquals("Wrong original config" , handle, wc.getOriginal()); //$NON-NLS-1$
		assertEquals("Wrong original config" , handle, nested.getOriginal()); //$NON-NLS-1$

		// cleanup
		handle.delete();
		assertTrue("Config should not exist after deletion", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Creates a configuration in an EFS linked folder. Deletes configuration
	 * directly.
	 *
	 * @throws CoreException
	 * @throws URISyntaxException
	 */
	@Test
	public void testCreateDeleteEFS() throws CoreException, URISyntaxException {
		IFileSystem fileSystem = EFS.getFileSystem("debug"); //$NON-NLS-1$
		assertNotNull("Missing debug EFS", fileSystem); //$NON-NLS-1$

		// create folder in EFS
		IFolder folder = getProject().getFolder("efs"); //$NON-NLS-1$
		folder.createLink(new URI("debug", Path.ROOT.toString(), null), 0, null); //$NON-NLS-1$

		// create configuration
		ILaunchConfigurationWorkingCopy wc = newConfiguration(folder, "efsConfig"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// delete configuration
		handle.delete();
		assertTrue("Configuration should not exist", !handle.exists()); //$NON-NLS-1$

		// cleanup
		folder.delete(IResource.NONE, null);
	}

	/**
	 * Creates a configuration in an EFS linked folder. Deletes the folder to
	 * ensure the configuration is also deleted.
	 *
	 * @throws CoreException
	 * @throws URISyntaxException
	 */
	@Test
	public void testCreateDeleteEFSLink() throws CoreException, URISyntaxException {
		IFileSystem fileSystem = EFS.getFileSystem("debug"); //$NON-NLS-1$
		assertNotNull("Missing debug EFS", fileSystem); //$NON-NLS-1$

		// create folder in EFS
		IFolder folder = getProject().getFolder("efs2"); //$NON-NLS-1$
		folder.createLink(new URI("debug", Path.ROOT.toString(), null), 0, null); //$NON-NLS-1$

		// create configuration
		ILaunchConfigurationWorkingCopy wc = newConfiguration(folder, "efsConfig"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// cleanup
		folder.delete(IResource.NONE, null);
		assertTrue("Configuration should not exist", !handle.exists()); //$NON-NLS-1$
	}

	/**
	 * Test that renaming a project with a linked EFS folder containing a shared
	 * launch configuration is properly updated.
	 *
	 * @throws Exception
	 */
	@Test
	public void testEFSProjectRename() throws Exception {
		// create test project
		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject("RenameEFS"); //$NON-NLS-1$
		if (pro.exists()) {
			pro.delete(true, true, null);
		}
		// create project
		IProject project = TestsPlugin.createProject("RenameEFS"); //$NON-NLS-1$

		IFileSystem fileSystem = EFS.getFileSystem("debug"); //$NON-NLS-1$
		assertNotNull("Missing debug EFS", fileSystem); //$NON-NLS-1$

		// create folder in EFS
		IFolder folder = project.getFolder("efs2"); //$NON-NLS-1$
		folder.createLink(new URI("debug", Path.ROOT.toString(), null), 0, null); //$NON-NLS-1$

		// create configuration
		ILaunchConfigurationWorkingCopy wc = newConfiguration(folder, "efsConfig"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// rename project
		IProjectDescription description = project.getDescription();
		description.setName("SFEemaneR"); // reverse name //$NON-NLS-1$
		project.move(description, IResource.SHALLOW, null);

		// original configuration should no longer exist - handle out of date
		assertTrue("Configuration should not exist", !handle.exists()); //$NON-NLS-1$

		// get the new handle
		project = ResourcesPlugin.getWorkspace().getRoot().getProject("SFEemaneR"); //$NON-NLS-1$
		assertTrue("Project should exist", project.exists()); //$NON-NLS-1$
		IFile file = project.getFile(new Path("efs2/efsConfig.launch")); //$NON-NLS-1$
		assertTrue("launch config file should exist", file.exists()); //$NON-NLS-1$
		handle = getLaunchManager().getLaunchConfiguration(file);
		assertTrue("launch config should exist", handle.exists()); //$NON-NLS-1$

		// retrieve attributes
		assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$

		// validate shared location
		assertEquals("Shared location should be updated", file, handle.getFile()); //$NON-NLS-1$

		// cleanup
		project.delete(IResource.NONE, null);
		assertTrue("Configuration should not exist", !handle.exists()); //$NON-NLS-1$

	}

	/**
	 * Tests launch configuration import.
	 *
	 * @throws Exception
	 */
	@Test
	public void testImport() throws Exception {
		// create a shared configuration "Import4" in the workspace to be overwritten on import
		ILaunchConfigurationWorkingCopy wc = newConfiguration(getProject(), "Import4"); //$NON-NLS-1$
		ILaunchConfiguration handle = wc.doSave();
		assertTrue("Configuration should exist", handle.exists()); //$NON-NLS-1$

		File dir = TestsPlugin.getDefault().getFileInPlugin(new Path("test-import")); //$NON-NLS-1$
		assertTrue("Import directory does not exist", dir.exists()); //$NON-NLS-1$
		LaunchManager manager = (LaunchManager) getLaunchManager();

		Listener listener = new Listener();
		try {
			getLaunchManager().addLaunchConfigurationListener(listener);
			// import
			manager.importConfigurations(dir.listFiles(
					(FileFilter) file -> file.isFile() && file.getName().endsWith(ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION)),
				null);

			// should be one removed
			List<ILaunchConfiguration> removed = listener.getRemoved();
			assertEquals("Should be one removed config", 1, removed.size()); //$NON-NLS-1$
			assertTrue("Import4 should be removed", removed.contains(handle)); //$NON-NLS-1$

			// should be 5 added
			List<?> added = listener.getAdded();
			assertEquals("Should be 5 added configs", 5, added.size()); //$NON-NLS-1$
			Set<String> names = new HashSet<>();
			Iterator<?> iterator = added.iterator();
			while (iterator.hasNext()) {
				ILaunchConfiguration lc = (ILaunchConfiguration) iterator.next();
				names.add(lc.getName());
			}
			assertTrue("Missing Name", names.contains("Import1")); //$NON-NLS-1$ //$NON-NLS-2$
			assertTrue("Missing Name", names.contains("Import2")); //$NON-NLS-1$ //$NON-NLS-2$
			assertTrue("Missing Name", names.contains("Import3")); //$NON-NLS-1$ //$NON-NLS-2$
			assertTrue("Missing Name", names.contains("Import4")); //$NON-NLS-1$ //$NON-NLS-2$
			assertTrue("Missing Name", names.contains("Import5")); //$NON-NLS-1$ //$NON-NLS-2$

			// should be one changed
			List<ILaunchConfiguration> changed = listener.getChanged();
			assertEquals("Should be 1 changed config", 1, changed.size()); //$NON-NLS-1$
			assertEquals("Wrong changed config", "Import4", changed.get(0).getName()); //$NON-NLS-1$ //$NON-NLS-2$
		} finally {
			manager.removeLaunchConfigurationListener(listener);
		}

	}

	/**
	 * Tests the location of a local working copy.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testWorkingCopyGetLocation() throws CoreException {
		ILaunchConfigurationWorkingCopy workingCopy = newConfiguration(null, "test-get-location"); //$NON-NLS-1$
		IPath location = workingCopy.getLocation();
		assertEquals("Wrong path for local working copy", LaunchManager.LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH.append("test-get-location.launch"), location); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests that the framework adds launch time stamps to launch objects.
	 */
	@Test
	public void testLaunchTimeStamp() throws CoreException {
		ILaunchConfigurationWorkingCopy workingCopy = newConfiguration(null, "test-time-stamp"); //$NON-NLS-1$
		ILaunch launch = workingCopy.launch(ILaunchManager.DEBUG_MODE, null);
		try {
			String stamp = launch.getAttribute(DebugPlugin.ATTR_LAUNCH_TIMESTAMP);
			assertNotNull("missing time stamp", stamp); //$NON-NLS-1$
			long lstamp = Long.parseLong(stamp); // should be a long - will throw NumberFormatException if not
			assertTrue("Time travel launch", lstamp <= System.currentTimeMillis());
		} finally {
			if (launch != null) {
				getLaunchManager().removeLaunch(launch);
			}
		}
	}

	/**
	 * Tests that the framework adds terminate time stamps to launch and process
	 * objects.
	 */
	@Test
	public void testTerminateTimeStamp() throws Exception {
		ILaunchConfigurationWorkingCopy workingCopy = newConfiguration(null, "test-time-stamp"); //$NON-NLS-1$
		ILaunch launch = workingCopy.launch(ILaunchManager.DEBUG_MODE, null);
		AtomicBoolean launchTerminated = new AtomicBoolean();
		ILaunchesListener2 listener = new ILaunchesListener2() {
			@Override
			public void launchesRemoved(ILaunch[] launches) {
			}

			@Override
			public void launchesChanged(ILaunch[] launches) {
			}

			@Override
			public void launchesAdded(ILaunch[] launches) {
			}

			@Override
			public void launchesTerminated(ILaunch[] launches) {
				for (ILaunch l : launches) {
					if (l == launch) {
						launchTerminated.set(true);
					}
				}
			}
		};
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(listener);
		IProcess process = null;
		try {
			process = DebugPlugin.newProcess(launch, new MockProcess(0), "test-terminate-timestamp");
			waitWhile(c -> !launchTerminated.get(), testTimeout, c -> "Launch did not finished");
			String stamp = launch.getAttribute(DebugPlugin.ATTR_TERMINATE_TIMESTAMP);
			assertNotNull("missing time stamp", stamp); //$NON-NLS-1$
			long lstamp = Long.parseLong(stamp); // should be a long - will throw NumberFormatException if not
			assertTrue("Time travel launch", lstamp <= System.currentTimeMillis());
		} finally {
			DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(listener);
			if (launch != null) {
				getLaunchManager().removeLaunch(launch);
			}
			if (process != null) {
				process.terminate();
			}
		}
	}

	/**
	 * Tests that attributes in a nested map are persisted in alphabetical
	 * order.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testMapAttributePersistence() throws CoreException, IOException {
		ILaunchConfigurationWorkingCopy c1 = newEmptyConfiguration(getProject(), "testMapAttributes1"); //$NON-NLS-1$
		HashMap<String, String> map = new HashMap<>();
		map.put("Z", "z-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("Y", "y-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("X", "x-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("W", "w-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("V", "v-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("U", "u-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("T", "t-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("S", "s-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("R", "r-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("Q", "q-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("P", "p-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("O", "o-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("N", "n-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("M", "m-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("L", "l-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("K", "k-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("J", "j-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("I", "i-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("H", "h-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("G", "g-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("F", "f-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("E", "e-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("D", "d-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("C", "c-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("B", "b-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("A", "a-value"); //$NON-NLS-1$ //$NON-NLS-2$
		c1.setAttribute("Map-Attribute", map); //$NON-NLS-1$
		c1.doSave();

		ILaunchConfigurationWorkingCopy c2 = newEmptyConfiguration(getProject(), "testMapAttributes2"); //$NON-NLS-1$
		map = new HashMap<>();
		map.put("A", "a-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("Z", "z-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("B", "b-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("Y", "y-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("C", "c-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("X", "x-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("D", "d-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("W", "w-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("E", "e-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("V", "v-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("F", "f-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("U", "u-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("G", "g-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("T", "t-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("H", "h-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("S", "s-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("I", "i-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("R", "r-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("J", "j-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("Q", "q-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("K", "k-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("P", "p-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("L", "l-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("M", "m-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("O", "o-value"); //$NON-NLS-1$ //$NON-NLS-2$
		map.put("N", "n-value"); //$NON-NLS-1$ //$NON-NLS-2$
		c2.setAttribute("Map-Attribute", map); //$NON-NLS-1$
		c2.doSave();

		// file contents should be the same
		char[] chars1, chars2;
		try (InputStream in1 = c1.getFile().getContents(); InputStream in2 = c2.getFile().getContents()) {
			chars1 = getInputStreamAsCharArray(in1);
			chars2 = getInputStreamAsCharArray(in2);
		}
		assertEquals("Should be the same characters", chars1.length, chars2.length); //$NON-NLS-1$
		for (int i = 0; i < chars2.length; i++) {
			assertEquals("Should be the same character", chars1[i], chars2[i]); //$NON-NLS-1$
		}

	}

	/**
	 * Tests that attributes in a nested set are persisted in alphabetical
	 * order.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testSetAttributePersistence() throws CoreException, IOException {
		ILaunchConfigurationWorkingCopy c1 = newEmptyConfiguration(getProject(), "testSetAttributes1"); //$NON-NLS-1$
		Set<String> set = new HashSet<>();
		set.add("z-value"); //$NON-NLS-1$
		set.add("y-value"); //$NON-NLS-1$
		set.add("x-value"); //$NON-NLS-1$
		set.add("w-value"); //$NON-NLS-1$
		set.add("v-value"); //$NON-NLS-1$
		set.add("u-value"); //$NON-NLS-1$
		set.add("t-value"); //$NON-NLS-1$
		set.add("s-value"); //$NON-NLS-1$
		set.add("r-value"); //$NON-NLS-1$
		set.add("q-value"); //$NON-NLS-1$
		set.add("p-value"); //$NON-NLS-1$
		set.add("o-value"); //$NON-NLS-1$
		set.add("n-value"); //$NON-NLS-1$
		set.add("m-value"); //$NON-NLS-1$
		set.add("l-value"); //$NON-NLS-1$
		set.add("k-value"); //$NON-NLS-1$
		set.add("j-value"); //$NON-NLS-1$
		set.add("i-value"); //$NON-NLS-1$
		set.add("h-value"); //$NON-NLS-1$
		set.add("g-value"); //$NON-NLS-1$
		set.add("f-value"); //$NON-NLS-1$
		set.add("e-value"); //$NON-NLS-1$
		set.add("d-value"); //$NON-NLS-1$
		set.add("c-value"); //$NON-NLS-1$
		set.add("b-value"); //$NON-NLS-1$
		set.add("a-value"); //$NON-NLS-1$
		c1.setAttribute("Set-Attribute", set); //$NON-NLS-1$
		c1.doSave();

		ILaunchConfigurationWorkingCopy c2 = newEmptyConfiguration(getProject(), "testSetAttributes2"); //$NON-NLS-1$
		set = new HashSet<>();
		set.add("a-value"); //$NON-NLS-1$
		set.add("z-value"); //$NON-NLS-1$
		set.add("b-value"); //$NON-NLS-1$
		set.add("y-value"); //$NON-NLS-1$
		set.add("c-value"); //$NON-NLS-1$
		set.add("x-value"); //$NON-NLS-1$
		set.add("d-value"); //$NON-NLS-1$
		set.add("w-value"); //$NON-NLS-1$
		set.add("e-value"); //$NON-NLS-1$
		set.add("v-value"); //$NON-NLS-1$
		set.add("f-value"); //$NON-NLS-1$
		set.add("u-value"); //$NON-NLS-1$
		set.add("g-value"); //$NON-NLS-1$
		set.add("t-value"); //$NON-NLS-1$
		set.add("h-value"); //$NON-NLS-1$
		set.add("s-value"); //$NON-NLS-1$
		set.add("i-value"); //$NON-NLS-1$
		set.add("r-value"); //$NON-NLS-1$
		set.add("j-value"); //$NON-NLS-1$
		set.add("q-value"); //$NON-NLS-1$
		set.add("k-value"); //$NON-NLS-1$
		set.add("p-value"); //$NON-NLS-1$
		set.add("l-value"); //$NON-NLS-1$
		set.add("m-value"); //$NON-NLS-1$
		set.add("o-value"); //$NON-NLS-1$
		set.add("n-value"); //$NON-NLS-1$
		c2.setAttribute("Set-Attribute", set); //$NON-NLS-1$
		c2.doSave();

		// file contents should be the same
		char[] chars1, chars2;
		try (InputStream in1 = c1.getFile().getContents(); InputStream in2 = c2.getFile().getContents()) {
			chars1 = getInputStreamAsCharArray(in1);
			chars2 = getInputStreamAsCharArray(in2);
		}
		assertEquals("Should be the same characters", chars1.length, chars2.length); //$NON-NLS-1$
		for (int i = 0; i < chars2.length; i++) {
			assertEquals("Should be the same character", chars1[i], chars2[i]); //$NON-NLS-1$
		}

	}

	/**
	 * Ensures that client does not attempt to nest configurations in a sub
	 * directory when using local metadata location. See bug 275741.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testIllegalFileSepCharName() {
		try {
			newConfiguration(null, new Path("some").append("nested").append("config").toOSString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		} catch (CoreException e) {
			// i.e. expected code path
			return;
		}
		assertTrue("Should be an illegal argument - cannot nest local configurations", false); //$NON-NLS-1$
	}

	/**
	 * Ensures that client can nest configurations in a sub directory when using
	 * a workspace location. See bug 275741. For behavior compatibility a client
	 * should be able to use a slash in the configuration name.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testLegalFileSepCharName() {
		try {
			newConfiguration(getProject(), new Path("some").append("nested").append("config").toOSString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		} catch (CoreException e) {
			assertTrue("Should *not* be an illegal argument - can nest shared cofigurations", false); //$NON-NLS-1$
		}
	}

	/**
	 * Test that an illegal name with '<' causes an exception
	 *
	 * @throws CoreException
	 */
	@Test
	public void testIllegalCharName() {
		try {
			newConfiguration(getProject(), "<config>"); //$NON-NLS-1$
		} catch (CoreException e) {
			// expected code path
			return;
		}
		assertTrue("Should be an illegal argument - illegal character used in name", false); //$NON-NLS-1$
	}

	/**
	 * Test that moving and renaming a shared configuration at the same time
	 * works.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testRenameAndMoveShared() throws CoreException {
		IProject project = getProject();
		IFolder f1 = project.getFolder("f1"); //$NON-NLS-1$
		IFolder f2 = project.getFolder("f2"); //$NON-NLS-1$
		f1.create(false, true, null);
		f2.create(false, true, null);
		ILaunchConfigurationWorkingCopy wc = newConfiguration(f1, "start-here"); //$NON-NLS-1$
		ILaunchConfiguration orig = wc.doSave();
		wc = orig.getWorkingCopy();

		wc.setContainer(f2);
		wc.rename("end-here"); //$NON-NLS-1$
		ILaunchConfiguration next = wc.doSave();

		assertFalse("Original should not exist", orig.exists()); //$NON-NLS-1$
		assertTrue("Renamed and moved config should exist", next.exists()); //$NON-NLS-1$

	}

	/**
	 * Test support for a URL in the 'icon' part of the
	 * launchConfigurationTypeImages extension point
	 *
	 * Bug 381175 - [patch] launchConfigurationTypeImage to support platform:
	 * style icons
	 *
	 * @throws Exception
	 */
	@Test
	public void testGetTypeImageFromURI() throws Exception {
		ImageDescriptor descriptor = DebugUITools.getImageDescriptor("org.eclipse.debug.tests.launch.type1"); //$NON-NLS-1$
		assertNotNull("The image descriptior type.image.1 must exist", descriptor); //$NON-NLS-1$
		assertNotSame("The image descriptor is not type.image.1", ImageDescriptor.getMissingImageDescriptor(), descriptor); //$NON-NLS-1$
	}

	/**
	 * Test support for a declared launch configuration type image
	 *
	 * @throws Exception
	 */
	@Test
	public void testGetTyeImage() throws Exception {
		ImageDescriptor descriptor = DebugUITools.getImageDescriptor("org.eclipse.debug.tests.launch.type"); //$NON-NLS-1$
		assertNotNull("The image descriptior type.image.2 must exist", descriptor); //$NON-NLS-1$
		assertNotSame("The image descriptor is not type.image.2", ImageDescriptor.getMissingImageDescriptor(), descriptor); //$NON-NLS-1$
	}

	/**
	 * Tests that we can get a project handle from a project name
	 *
	 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=395441
	 * @throws Exception
	 * @since 3.9.0
	 */
	@Test
	public void testGetProjectMappedResource1() throws Exception {
		ILaunchConfiguration lc = newConfiguration(null, "test.project.resource.mapping"); //$NON-NLS-1$
		try {
			ILaunchConfigurationWorkingCopy wc = lc.getWorkingCopy();
			assertNotNull("Should have a working copy of the testig launch configuration", wc); //$NON-NLS-1$
			setResourceMappings(wc, new ResourceItem[] { new ResourceItem("test.project", Integer.valueOf(IResource.PROJECT)) }); //$NON-NLS-1$
			IResource[] res = wc.getMappedResources();
			assertNotNull("There should be mapped resources", res); //$NON-NLS-1$
			assertTrue("There should be one project", res.length == 1); //$NON-NLS-1$
		}
		finally {
			lc.delete();
		}
	}

	/**
	 * Tests that we cannot get a project handle from a bogus project name
	 *
	 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=395441
	 * @throws Exception
	 * @since 3.9.0
	 */
	@Test
	public void testGetProjectMappedResource2() throws Exception {
		ILaunchConfiguration lc = newConfiguration(null, "test.project.resource.mapping"); //$NON-NLS-1$
		try {
			ILaunchConfigurationWorkingCopy wc = lc.getWorkingCopy();
			assertNotNull("Should have a working copy of the testig launch configuration", wc); //$NON-NLS-1$
			setResourceMappings(wc, new ResourceItem[] { new ResourceItem("test/project", Integer.valueOf(IResource.PROJECT)) }); //$NON-NLS-1$
			IResource[] res = wc.getMappedResources();
			assertNull("There should be no mapped resources", res); //$NON-NLS-1$
		}
		finally {
			lc.delete();
		}
	}

	/**
	 * Tests that we cannot get a project handle from a bogus project name
	 *
	 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=395441
	 * @throws Exception
	 * @since 3.9.0
	 */
	@Test
	public void testGetProjectMappedResource3() throws Exception {
		ILaunchConfiguration lc = newConfiguration(null, "test.project.resource.mapping"); //$NON-NLS-1$
		try {
			ILaunchConfigurationWorkingCopy wc = lc.getWorkingCopy();
			assertNotNull("Should have a working copy of the testig launch configuration", wc); //$NON-NLS-1$
			setResourceMappings(wc, new ResourceItem[] { new ResourceItem("test\\project", Integer.valueOf(IResource.PROJECT)) }); //$NON-NLS-1$
			IResource[] res = wc.getMappedResources();
			if(Platform.OS_WIN32.equals(Platform.getOS())) {
				assertNull("There should be no mapped resources", res); //$NON-NLS-1$
			}
			else {
				assertNotNull("There should be mapped resources", res); //$NON-NLS-1$
			}
		}
		finally {
			lc.delete();
		}
	}

	/**
	 * Tests that we can get a project handle from an absolute project name
	 *
	 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=395441
	 * @throws Exception
	 * @since 3.9.0
	 */
	@Test
	public void testGetProjectMappedResource4() throws Exception {
		ILaunchConfiguration lc = newConfiguration(null, "test.project.resource.mapping"); //$NON-NLS-1$
		try {
			ILaunchConfigurationWorkingCopy wc = lc.getWorkingCopy();
			assertNotNull("Should have a working copy of the testig launch configuration", wc); //$NON-NLS-1$
			setResourceMappings(wc, new ResourceItem[] { new ResourceItem("/project", Integer.valueOf(IResource.PROJECT)) }); //$NON-NLS-1$
			IResource[] res = wc.getMappedResources();
			assertNotNull("There should be mapped resources", res); //$NON-NLS-1$
		}
		finally {
			lc.delete();
		}
	}

	/**
	 * Tests that a launch created without a backing
	 * {@link ILaunchConfiguration} does not cause {@link NullPointerException}s
	 *
	 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=416691
	 * @throws Exception
	 * @since 3.9.0
	 */
	@Test
	public void testNullLaunchConfigurationInLaunch() throws Exception {
		Launch l = new Launch(null, ILaunchManager.RUN_MODE, null);
		LaunchManager lm = (LaunchManager) DebugPlugin.getDefault().getLaunchManager();
		// find the external tools UI bundle and make sure it is started
		Bundle b = Platform.getBundle("org.eclipse.ui.externaltools"); //$NON-NLS-1$
		assertNotNull("Must have found the external tools bundle", b); //$NON-NLS-1$
		if (b.getState() != Bundle.ACTIVE) {
			b.start();
		}
		// no NPE should be logged
		lm.addLaunch(l);
	}

	/**
	 * Proxy to set resource paths, allowing invalid resource paths to be set
	 *
	 * @param resources
	 * @since 3.9.0
	 */
	protected void setResourceMappings(ILaunchConfigurationWorkingCopy config, ResourceItem[] resources) {
		List/* <String> */<String> paths = null;
		List/* <String> */<String> types = null;
		int size = resources.length;
		if(resources != null && size > 0) {
			paths = new ArrayList<>(size);
			types = new ArrayList<>(size);
			for(int i = 0; i < size; i++) {
				paths.add(resources[i].path);
				types.add(resources[i].type.toString());
			}
		}
		config.setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_PATHS, paths);
		config.setAttribute(LaunchConfiguration.ATTR_MAPPED_RESOURCE_TYPES, types);
	}

	/**
	 * Test copying attributes from one configuration to another.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testCopyAttributes() throws CoreException {
		ILaunchConfigurationWorkingCopy source = newPrototype(null, "test-copy-attributes-source"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy dest = newEmptyConfiguration(null, "test-copy-attributes-dest"); //$NON-NLS-1$
		dest.copyAttributes(source);
		assertTrue("String1 should be String1", dest.getAttribute("String1", "Missing").equals("String1"));  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		assertTrue("Int1 should be 1", dest.getAttribute("Int1", 0) == 1); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean1 should be true", dest.getAttribute("Boolean1", false)); //$NON-NLS-1$ //$NON-NLS-2$
		assertTrue("Boolean2 should be false", !dest.getAttribute("Boolean2", true)); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Tests that creation from a prototype works.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testCreationFromPrototype() throws CoreException {
		ILaunchConfigurationWorkingCopy temp = newPrototype(null, "test-creation-from-prototype"); //$NON-NLS-1$
		temp.setAttribute("TEMPLATE", "TEMPLATE"); //$NON-NLS-1$ //$NON-NLS-2$
		ILaunchConfiguration prototype = temp.doSave();
		ILaunchConfigurationType type = temp.getType();

		ILaunchConfigurationWorkingCopy config = type.newInstance(null, "test-scopes"); //$NON-NLS-1$
		config.setPrototype(prototype, true);
		assertNotNull("Made from wrong prototype", config.getAttribute("TEMPLATE", (String)null)); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("Should refer to creation prototype", prototype, config.getPrototype()); //$NON-NLS-1$
	}

	/**
	 * Tests setting the 'isPrototype' attribute.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testIsPrototype() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newPrototype(null, "test-is-prototype"); //$NON-NLS-1$
		ILaunchConfiguration prototype = wc.doSave();
		assertTrue("Should be a prototype", prototype.isPrototype()); //$NON-NLS-1$
		ILaunchConfiguration[] prototypes = wc.getType().getPrototypes();
		List<ILaunchConfiguration> list = new ArrayList<>();
		Collections.addAll(list, prototypes);
		assertFalse("Expecting at least prototype", list.isEmpty()); //$NON-NLS-1$
		assertTrue("Missing created prototype", list.contains(prototype)); //$NON-NLS-1$
	}

	/**
	 * Tests finding references to a prototype.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testPrototypeChildren() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newPrototype(null, "test-references"); //$NON-NLS-1$
		ILaunchConfiguration prototype = wc.doSave();

		ILaunchConfigurationWorkingCopy r1 = newConfiguration(null, "referee-1"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy r2 = newConfiguration(null, "referee-2"); //$NON-NLS-1$

		r1.setPrototype(prototype, false);
		r2.setPrototype(prototype, false);

		ILaunchConfiguration s1 = r1.doSave();
		ILaunchConfiguration s2 = r2.doSave();

		Iterable<ILaunchConfiguration> children = prototype.getPrototypeChildren();
		List<ILaunchConfiguration> list = new ArrayList<>();
		for (ILaunchConfiguration child : children) {
			list.add(child);
		}
		assertEquals("Wrong number of prototype children", 2, list.size()); //$NON-NLS-1$
		assertTrue("Missing reference", list.contains(s1)); //$NON-NLS-1$
		assertTrue("Missing reference", list.contains(s2)); //$NON-NLS-1$
	}

	/**
	 * Tests that when an attribute is removed from a working copy, it does not
	 * get inherited from its prototype.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testPrototypeRemoveBehavior() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "test-remove"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy t1 = newEmptyPrototype(null, "prototype-1"); //$NON-NLS-1$
		t1.setAttribute("COMMON", "TEMPLATE-1"); //$NON-NLS-1$ //$NON-NLS-2$
		t1.setAttribute("T1", "T1"); //$NON-NLS-1$ //$NON-NLS-2$
		t1.setAttribute("String1", "String2"); //$NON-NLS-1$ //$NON-NLS-2$
		ILaunchConfiguration prototype = t1.doSave();

		assertEquals("String1", wc.getAttribute("String1", "wrong")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		wc.setPrototype(prototype, true);
		wc.removeAttribute("String1"); //$NON-NLS-1$
		assertEquals("TEMPLATE-1", wc.getAttribute("COMMON", (String)null)); //$NON-NLS-1$ //$NON-NLS-2$
		assertEquals("T1", wc.getAttribute("T1", (String)null)); //$NON-NLS-1$ //$NON-NLS-2$
		assertNull(wc.getAttribute("String1", (String)null)); //$NON-NLS-1$

	}

	/**
	 * Tests that setting a configuration's prototype to null cleans its
	 * prototype association.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testUnPrototype() throws CoreException {
		ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "test-un-prototype"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy t1 = newEmptyPrototype(null, "prototype-un"); //$NON-NLS-1$
		t1.setAttribute("COMMON", "PROTOTYPE-1"); //$NON-NLS-1$ //$NON-NLS-2$
		t1.setAttribute("T1", "T1"); //$NON-NLS-1$ //$NON-NLS-2$
		t1.setAttribute("String1", "String2"); //$NON-NLS-1$ //$NON-NLS-2$
		ILaunchConfiguration prototype = t1.doSave();
		wc.setPrototype(prototype, true);
		ILaunchConfiguration configuration = wc.doSave();
		assertEquals(prototype, configuration.getPrototype());
		wc = configuration.getWorkingCopy();
		wc.setPrototype(null, false);
		configuration = wc.doSave();
		assertNull(configuration.getPrototype());
		Iterable<ILaunchConfiguration> children = t1.getPrototypeChildren();
		assertFalse(children.iterator().hasNext());
	}

	/**
	 * Tests that nested prototypes are not allowed.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testNestedPrototypes() throws CoreException {
		ILaunchConfigurationWorkingCopy t1 = newPrototype(null, "test-nest-root"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy t2 = newPrototype(null, "prototype-nested"); //$NON-NLS-1$
		ILaunchConfiguration prototype = t1.doSave();
		try {
			t2.setPrototype(prototype, true);
		} catch (CoreException e) {
			return;
		}
		assertTrue("Shoud not be able to nest prototypes", false); //$NON-NLS-1$
	}

	/**
	 * Test that you cannot set a config's prototype to be a non-prototype.
	 *
	 * @throws CoreException
	 */
	@Test
	public void testIllegalPrototype() throws CoreException {
		ILaunchConfigurationWorkingCopy c1 = newConfiguration(null, "test-config"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy t1 = newConfiguration(null, "test-not-a-prototype"); //$NON-NLS-1$
		ILaunchConfiguration config = t1.doSave();
		try {
			c1.setPrototype(config, true);
		} catch (CoreException e) {
			// expected
			return;
		}
		assertTrue("Should not be able to set configration as prototype", false); //$NON-NLS-1$
	}

	/**
	 * Test that a prototype can be duplicated (and results in a prototype).
	 *
	 * @throws CoreException
	 */
	@Test
	public void testCopyPrototype() throws CoreException {
		ILaunchConfigurationWorkingCopy t1 = newEmptyPrototype(null, "prototype-to-duplicate"); //$NON-NLS-1$
		ILaunchConfigurationWorkingCopy t2 = t1.copy("duplicate-prototype"); //$NON-NLS-1$
		assertTrue(t2.isPrototype());
	}

	@Test
	public void testNewInstanceNotifiesListener() throws CoreException {
		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
		final ArrayList<String> added = new ArrayList<>();
		ILaunchConfigurationListener listener = new ILaunchConfigurationListener() {

			@Override
			public void launchConfigurationRemoved(ILaunchConfiguration configuration) {

			}

			@Override
			public void launchConfigurationChanged(ILaunchConfiguration configuration) {

			}

			@Override
			public void launchConfigurationAdded(ILaunchConfiguration configuration) {
				added.add("Launch Configuration added");

			}
		};
		launchManager.addLaunchConfigurationListener(listener);
		String typeId = "org.eclipse.ui.externaltools.ProgramLaunchConfigurationType";

		ILaunchConfigurationType type = launchManager.getLaunchConfigurationType(typeId);
		type.newInstance(null, "new-lc").doSave();
		assertEquals(1, added.size());
		assertEquals("Launch Configuration added", added.get(0));

	}

}
