/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * 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
 *     Sascha Radike - bug 56642
 *     Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes
 *******************************************************************************/
package org.eclipse.debug.internal.core;


import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
import org.eclipse.debug.core.model.IPersistableSourceLocator;
import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.ibm.icu.text.MessageFormat;

/**
 * Launch configuration handle.
 *
 * @see ILaunchConfiguration
 */
public class LaunchConfiguration extends PlatformObject implements ILaunchConfiguration {

	/**
	 * Launch configuration attribute that specifies the resources paths mapped to it.
	 * Not all launch configurations will have a mapped resource unless migrated.
	 * Value is a list of resource paths stored as portable strings, or <code>null</code>
	 * if none.
	 *
	 * @since 3.2
	 */
	public static final String ATTR_MAPPED_RESOURCE_PATHS = DebugPlugin.getUniqueIdentifier() + ".MAPPED_RESOURCE_PATHS"; //$NON-NLS-1$

	/**
	 * Launch configuration attribute that specifies the resources types mapped to it.
	 * Not all launch configurations will have a mapped resource unless migrated.
	 * Value is a list of resource type integers, or <code>null</code> if none.
	 *
	 * @since 3.2
	 */
	public static final String ATTR_MAPPED_RESOURCE_TYPES = DebugPlugin.getUniqueIdentifier() + ".MAPPED_RESOURCE_TYPES"; //$NON-NLS-1$

	/**
	 * The launch modes set on this configuration.
	 *
	 * @since 3.3
	 */
	public static final String ATTR_LAUNCH_MODES = DebugPlugin.getUniqueIdentifier() + ".LAUNCH_MODES"; //$NON-NLS-1$

	/**
	 * Launch configuration attribute storing a list
	 * of preferred launchers for associated mode sets.
	 * This attribute is a list of launchers stored by mode set
	 * and relating to the id of the preferred launcher, which happens to be an <code>ILaunchDelegate</code>
	 *
	 * @since 3.3
	 */
	public static final String ATTR_PREFERRED_LAUNCHERS = DebugPlugin.getUniqueIdentifier() + ".preferred_launchers"; //$NON-NLS-1$

	/**
	 * Launch configuration attribute storing a memento identifying the prototype
	 * this configuration was made from, possibly <code>null</code>.
	 *
	 *  @since 3.12
	 */
	public static final String ATTR_PROTOTYPE = DebugPlugin.getUniqueIdentifier() + ".ATTR_PROTOTYPE"; //$NON-NLS-1$

	/**
	 * Launch configuration attribute storing if this configuration is a
	 * prototype or not.
	 *
	 * @since 3.12
	 */
	public static final String IS_PROTOTYPE = DebugPlugin.getUniqueIdentifier() + ".IS_PROTOTYPE"; //$NON-NLS-1$

	/**
	 * Status handler to prompt in the UI thread
	 *
	 * @since 3.3
	 */
	protected static final IStatus promptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200, "", null);  //$NON-NLS-1$//$NON-NLS-2$

	/**
	 * Status handler to prompt the user to resolve the missing launch delegate issue
	 * @since 3.3
	 */
	protected static final IStatus delegateNotAvailable = new Status(IStatus.INFO, "org.eclipse.debug.core", 226, "", null); //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * Status handle to prompt the user to resolve duplicate launch delegates being detected
	 *
	 *  @since 3.3
	 */
	protected static final IStatus duplicateDelegates = new Status(IStatus.INFO, "org.eclipse.debug.core", 227, "", null);  //$NON-NLS-1$//$NON-NLS-2$

	/**
	 * This configuration's name
	 * @since 3.5
	 */
	private String fName;

	/**
	 * The container this configuration is stored in or <code>null</code> if stored locally
	 * with workspace metadata.
	 * @since 3.5
	 */
	private IContainer fContainer;

	/**
	 * If this configuration is a prototype.
	 * @since 3.12
	 */
	private boolean fIsPrototype;

	/**
	 * Constructs a launch configuration with the given name. The configuration
	 * is stored in the given container or locally with workspace metadata if
	 * the specified container is <code>null</code>.
	 *
	 * @param name launch configuration name
	 * @param container parent container or <code>null</code>
	 * @since 3.5
	 */
	protected LaunchConfiguration(String name, IContainer container) {
		this(name, container, false);
	}

	/**
	 * Constructs a launch configuration with the given name. The configuration
	 * is stored in the given container or locally with workspace metadata if
	 * the specified container is <code>null</code>.
	 *
	 * @param name launch configuration name
	 * @param container parent container or <code>null</code>
	 * @param prototype if the configuration is a prototype or not
	 * @since 3.12
	 */
	protected LaunchConfiguration(String name, IContainer container, boolean prototype) {
		initialize();
		setName(name);
		setContainer(container);
		fIsPrototype = prototype;
	}

	/**
	 * Initialize any state variables - called first in the constructor.
	 * Subclasses must override as appropriate.
	 */
	protected void initialize() {
	}

	/**
	 * Constructs a launch configuration on the given workspace file.
	 *
	 * @param file workspace .launch file
	 * @since 3.5
	 */
	protected LaunchConfiguration(IFile file) {
		this(getSimpleName(file.getName()), file.getParent(), isPrototype(file));
	}

	/**
	 * Given a name that ends with .launch or .prototype, return the simple name of the configuration.
	 *
	 * @param fileName the name to parse
	 * @return simple name
	 * @since 3.5
	 */
	protected static String getSimpleName(String fileName) {
		IPath path = new Path(fileName);
		if(ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION.equals(path.getFileExtension())) {
			return path.removeFileExtension().toString();
		} else if (ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION.equals(path.getFileExtension())) {
			return path.removeFileExtension().toString();
		}
		return fileName;
	}

	/**
	 * Constructs a launch configuration from the given
	 * memento.
	 *
	 * @param memento launch configuration memento
	 * @exception CoreException if the memento is invalid or
	 * 	an exception occurs reading the memento
	 */
	protected LaunchConfiguration(String memento) throws CoreException {
		Exception ex = null;
		try {
			Element root = null;
			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			parser.setErrorHandler(new DefaultHandler());
			StringReader reader = new StringReader(memento);
			InputSource source = new InputSource(reader);
			root = parser.parse(source).getDocumentElement();

			String localString = root.getAttribute(IConfigurationElementConstants.LOCAL);
			String path = root.getAttribute(IConfigurationElementConstants.PATH);

			String message = null;
			if (path == null || IInternalDebugCoreConstants.EMPTY_STRING.equals(path)) {
				message = DebugCoreMessages.LaunchConfiguration_18;
			} else if (localString == null || IInternalDebugCoreConstants.EMPTY_STRING.equals(localString)) {
				message = DebugCoreMessages.LaunchConfiguration_19;
			}
			if (message != null) {
				throw new CoreException(newStatus(message, DebugException.INTERNAL_ERROR, null));
			}


			boolean local = (Boolean.valueOf(localString)).booleanValue();
			IPath iPath = new Path(path);
			String name = getSimpleName(iPath.lastSegment());
			IContainer container = null;
			if (!local) {
				container = ResourcesPlugin.getWorkspace().getRoot().getFile(iPath).getParent();
			}
			setName(name);
			setContainer(container);
			return;
		} catch (ParserConfigurationException e) {
			ex = e;
		} catch (SAXException e) {
			ex = e;
		} catch (IOException e) {
			ex = e;
		}
		IStatus s = newStatus(DebugCoreMessages.LaunchConfiguration_17, DebugException.INTERNAL_ERROR, ex);
		throw new CoreException(s);
	}

	@Override
	public boolean contentsEqual(ILaunchConfiguration object) {
		try {
			if (object instanceof LaunchConfiguration) {
				LaunchConfiguration otherConfig = (LaunchConfiguration) object;
				return getName().equals(otherConfig.getName())
					 && getType().equals(otherConfig.getType())
					 && equalOrNull(getContainer(), otherConfig.getContainer())
					 && getInfo().equals(otherConfig.getInfo());
			}
			return false;
		} catch (CoreException ce) {
			return false;
		}
	}

	@Override
	public ILaunchConfigurationWorkingCopy copy(String name) throws CoreException {
		ILaunchConfigurationWorkingCopy copy = new LaunchConfigurationWorkingCopy(this, name);
		return copy;
	}

	@Override
	public void delete() throws CoreException {
		if (exists()) {
			IFile file = getFile();
			if (file == null) {
				IFileStore store = getFileStore();
				if (store != null) {
					store.delete(EFS.NONE, null);
					if ((store.fetchInfo().exists())) {
						throw new DebugException(
							new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
							 DebugException.REQUEST_FAILED, DebugCoreMessages.LaunchConfiguration_Failed_to_delete_launch_configuration__1, null)
						);
					}
				}
			} else {
				// Delete the resource using IFile API such that
				// resource deltas are fired.
				// First do validate edit to ensure the resource is local
				if (file.isReadOnly()) {
					IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile[] {file}, null);
					if (!status.isOK()) {
						throw new CoreException(status);
					}
				}
				file.delete(true, null);
			}
			// update the launch manager cache synchronously
			getLaunchManager().launchConfigurationDeleted(this);
		}
	}

	@Override
	public void delete(int flag) throws CoreException {
		if (flag == UPDATE_PROTOTYPE_CHILDREN && isPrototype()) {
			// clear back pointers to this configuration
			Collection<ILaunchConfiguration> children = getPrototypeChildren();
			for (ILaunchConfiguration child : children) {
				ILaunchConfigurationWorkingCopy childWC = child.getWorkingCopy();
				childWC.setPrototype(null, false);
				childWC.doSave();
			}
		}
		delete();
	}

	/**
	 * Returns whether this configuration is equal to the
	 * given configuration. Two configurations are equal if
	 * they are stored in the same location (and neither one
	 * is a working copy).
	 *
	 * @return whether this configuration is equal to the
	 *  given configuration
	 * @see Object#equals(Object)
	 */
	@Override
	public boolean equals(Object object) {
		if (object instanceof ILaunchConfiguration) {
			if (isWorkingCopy()) {
				return this == object;
			}
			LaunchConfiguration config = (LaunchConfiguration) object;
			if (!config.isWorkingCopy()) {
				return getName().equals(config.getName()) &&
					equalOrNull(getContainer(), config.getContainer());
			}
		}
		return false;
	}

	/**
	 * Returns whether the given objects are equal or both <code>null</code>.
	 *
	 * @param o1 the object
	 * @param o2 the object to be compared to o1
	 * @return whether the given objects are equal or both <code>null</code>
	 * @since 3.5
	 */
	protected boolean equalOrNull(Object o1, Object o2) {
		if (o1 == null) {
			return o2 == null;
		} else if (o2 != null) {
			return o1.equals(o2);
		}
		return false;
	}

	@Override
	public boolean exists() {
		IFile file = getFile();
		if (file != null) {
			return file.exists();
		}
		try {
			IFileStore store = getFileStore();
			if (store != null) {
				return store.fetchInfo().exists();
			}
		} catch (CoreException e) {
		}
		return false;
	}

	@Override
	public boolean getAttribute(String attributeName, boolean defaultValue) throws CoreException {
		return getInfo().getBooleanAttribute(attributeName, defaultValue);
	}

	@Override
	public int getAttribute(String attributeName, int defaultValue) throws CoreException {
		return getInfo().getIntAttribute(attributeName, defaultValue);
	}

	@Override
	public List<String> getAttribute(String attributeName, List<String> defaultValue) throws CoreException {
		return getInfo().getListAttribute(attributeName, defaultValue);
	}

	@Override
	public Set<String> getAttribute(String attributeName, Set<String> defaultValue) throws CoreException {
		return getInfo().getSetAttribute(attributeName, defaultValue);
	}

	@Override
	public Map<String, String> getAttribute(String attributeName, Map<String, String> defaultValue) throws CoreException {
		return getInfo().getMapAttribute(attributeName, defaultValue);
	}

	@Override
	public String getAttribute(String attributeName, String defaultValue) throws CoreException {
		return getInfo().getStringAttribute(attributeName, defaultValue);
	}

	@Override
	public Map<String, Object> getAttributes() throws CoreException {
		LaunchConfigurationInfo info = getInfo();
		return info.getAttributes();
	}

	@Override
	public String getCategory() throws CoreException {
		return getType().getCategory();
	}

	@Override
	public IFile getFile() {
		IContainer container = getContainer();
		if (container != null) {
			return container.getFile(new Path(getFileName()));
		}
		return null;
	}

	/**
	 * Returns the simple file name of this launch configuration.
	 *
	 * @return the simple file name of this launch configuration - for example
	 *  	"Abc.launch" or "Abc.prototype"
	 */
	protected String getFileName() {
		StringBuilder buf = new StringBuilder(getName());
		buf.append('.');
		if (isPrototype()) {
			buf.append(ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION);
		} else {
			buf.append(ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION);
		}
		return buf.toString();
	}

	/**
	 * Returns the info object containing the attributes
	 * of this configuration
	 *
	 * @return info for this handle
	 * @exception CoreException if unable to retrieve the
	 *  info object
	 */
	protected LaunchConfigurationInfo getInfo() throws CoreException {
		return getLaunchManager().getInfo(this);
	}

	/**
	 * Returns the launch manager
	 *
	 * @return launch manager
	 */
	protected LaunchManager getLaunchManager() {
		return (LaunchManager)DebugPlugin.getDefault().getLaunchManager();
	}

	@Override
	public IPath getLocation() {
		try {
			IFileStore store = getFileStore();
			if (store != null) {
				File localFile = store.toLocalFile(EFS.NONE, null);
				if (localFile != null) {
					return new Path(localFile.getAbsolutePath());
				}
			}
		} catch (CoreException e) {
		}
		return null;
	}

	/**
	 * Returns the file store this configuration is persisted in or <code>null</code> if
	 * a file store cannot be derived. The file may or may not exist. If this configuration
	 * is in a project that is closed or does not exist, <code>null</code> is returned.
	 *
	 * @return file store this configuration is persisted in or <code>null</code>
	 * @throws CoreException if a problem is encountered
	 * @since 3.5
	 */
	public IFileStore getFileStore() throws CoreException {
		if (isLocal()) {
			return EFS.getLocalFileSystem().fromLocalFile(
				LaunchManager.LOCAL_LAUNCH_CONFIGURATION_CONTAINER_PATH.append(getFileName()).toFile());
		}
		URI uri = getFile().getLocationURI();
		if (uri != null) {
			return EFS.getStore(uri);
		}
		return null;
	}

	@Override
	public IResource[] getMappedResources() throws CoreException {
		List<String> paths = getAttribute(ATTR_MAPPED_RESOURCE_PATHS, (List<String>) null);
		if (paths == null || paths.isEmpty()) {
			return null;
		}
		List<String> types = getAttribute(ATTR_MAPPED_RESOURCE_TYPES, (List<String>) null);
		if (types == null || types.size() != paths.size()) {
			throw new CoreException(newStatus(DebugCoreMessages.LaunchConfiguration_0, DebugPlugin.ERROR, null));
		}
		ArrayList<IResource> list = new ArrayList<>();
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		for(int i = 0; i < paths.size(); i++) {
			String pathStr = paths.get(i);
			String typeStr= types.get(i);
			int type = -1;
			try {
				type = Integer.decode(typeStr).intValue();
			} catch (NumberFormatException e) {
				throw new CoreException(newStatus(DebugCoreMessages.LaunchConfiguration_0, DebugPlugin.ERROR, e));
			}
			IPath path = Path.fromPortableString(pathStr);
			IResource res = null;
			switch (type) {
				case IResource.FILE:
					res = root.getFile(path);
					break;
				case IResource.PROJECT:
					pathStr = path.makeRelative().toPortableString();
					if(Path.ROOT.isValidSegment(pathStr)) {
						res = root.getProject(pathStr);
					}
					break;
				case IResource.FOLDER:
					res = root.getFolder(path);
					break;
				case IResource.ROOT:
					res = root;
					break;
				default:
					throw new CoreException(newStatus(DebugCoreMessages.LaunchConfiguration_0, DebugPlugin.ERROR, null));
			}
			if(res != null) {
				list.add(res);
			}
		}
		if (list.isEmpty()) {
			return null;
		}
		return list.toArray(new IResource[list.size()]);
	}

	@Override
	public String getMemento() throws CoreException {
		IPath relativePath = null;
		IFile file = getFile();
		boolean local = true;
		if (file == null) {
			relativePath = new Path(getName());
		} else {
			local = false;
			relativePath = file.getFullPath();
		}
		Exception e= null;
		try {
			Document doc = LaunchManager.getDocument();
			Element node = doc.createElement(IConfigurationElementConstants.LAUNCH_CONFIGURATION);
			doc.appendChild(node);
			node.setAttribute(IConfigurationElementConstants.LOCAL, (Boolean.valueOf(local)).toString());
			node.setAttribute(IConfigurationElementConstants.PATH, relativePath.toString());
			return LaunchManager.serializeDocument(doc);
		} catch (IOException ioe) {
			e= ioe;
		} catch (ParserConfigurationException pce) {
			e= pce;
		} catch (TransformerException te) {
			e= te;
		}
		IStatus status = newStatus(DebugCoreMessages.LaunchConfiguration_16, DebugException.INTERNAL_ERROR,  e);
		throw new CoreException(status);
	}

	@Override
	public String getName() {
		return fName;
	}

	/**
	 * Returns the container this configuration is stored in, or <code>null</code>
	 * if this configuration is local.
	 *
	 * @return the container this configuration is stored in, or <code>null</code>
	 * if this configuration is local
	 * @since 3.5
	 */
	protected IContainer getContainer() {
		return fContainer;
	}

	@Override
	public Set<String> getModes() throws CoreException {
		Set<String> options = getAttribute(ATTR_LAUNCH_MODES, (Set<String>) null);
		return (options != null ? new HashSet<>(options) : new HashSet<>(0));
	}

	@Override
	public ILaunchConfigurationType getType() throws CoreException {
		return getInfo().getType();
	}

	@Override
	public ILaunchConfigurationWorkingCopy getWorkingCopy() throws CoreException {
		return new LaunchConfigurationWorkingCopy(this);
	}

	@Override
	public int hashCode() {
		IContainer container = getContainer();
		if (container == null) {
			return getName().hashCode();
		} else {
			return getName().hashCode() + container.hashCode();
		}
	}

	@Override
	public boolean hasAttribute(String attributeName) throws CoreException {
		return getInfo().hasAttribute(attributeName);
	}

	/**
	 * Set the source locator to use with the launch, if specified
	 * by this configuration.
	 *
	 * @param launch the launch on which to set the source locator
	 * @throws CoreException if a problem is encountered
	 */
	protected void initializeSourceLocator(ILaunch launch) throws CoreException {
		if (launch.getSourceLocator() == null) {
			String type = getAttribute(ATTR_SOURCE_LOCATOR_ID, (String)null);
			if (type == null) {
				type = getType().getSourceLocatorId();
			}
			if (type != null) {
				IPersistableSourceLocator locator = getLaunchManager().newSourceLocator(type);
				String memento = getAttribute(ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
				if (memento == null) {
					locator.initializeDefaults(this);
				} else {
					if(locator instanceof IPersistableSourceLocator2) {
						((IPersistableSourceLocator2)locator).initializeFromMemento(memento, this);
					} else {
						locator.initializeFromMemento(memento);
					}
				}
				launch.setSourceLocator(locator);
			}
		}
	}

	@Override
	public boolean isLocal() {
		return getContainer() == null;
	}

	@Override
	public boolean isMigrationCandidate() throws CoreException {
		return ((LaunchConfigurationType)getType()).isMigrationCandidate(this);
	}

	@Override
	public boolean isWorkingCopy() {
		return false;
	}

	@Override
	public ILaunch launch(String mode, IProgressMonitor monitor) throws CoreException {
		return launch(mode, monitor, false);
	}

	@Override
	public ILaunch launch(String mode, IProgressMonitor monitor, boolean build) throws CoreException {
		return launch(mode, monitor, build, true);
	}

	@Override
	public ILaunch launch(String mode, IProgressMonitor monitor, boolean build, boolean register) throws CoreException {
		/* Setup progress monitor
		 * - Prepare delegate (0)
		 * - Pre-launch check (1)
		 * - [Build before launch (7)]					if build
		 * - [Incremental build before launch (3)]		if build
		 * - Final launch validation (1)
		 * - Initialize source locator (1)
		 * - Launch delegate (10) */
		SubMonitor lmonitor = SubMonitor.convert(monitor, DebugCoreMessages.LaunchConfiguration_9, 23);
		try {
			// bug 28245 - force the delegate to load in case it is interested in launch notifications
			Set<String> modes = getModes();
			modes.add(mode);
			ILaunchDelegate[] delegates = getType().getDelegates(modes);
			ILaunchConfigurationDelegate delegate = null;
			switch (delegates.length) {
				case 1:
					delegate = delegates[0].getDelegate();
					break;
				case 0:
				{
					IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(promptStatus);
					if (handler != null) {
						handler.handleStatus(delegateNotAvailable, new Object[] {this, mode});
					}
					IStatus status = new Status(IStatus.CANCEL, DebugPlugin.getUniqueIdentifier(), DebugPlugin.ERROR, DebugCoreMessages.LaunchConfiguration_11, null);
					throw new CoreException(status);
				}
				default:
				{
					ILaunchDelegate del = getPreferredDelegate(modes);
					if(del == null) {
						del = getType().getPreferredDelegate(modes);
					}
					if(del == null) {
						IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(promptStatus);
						IStatus status = null;
						if (handler != null) {
							status = (IStatus) handler.handleStatus(duplicateDelegates, new Object[] {this, mode});
						}
						if(status != null && status.isOK()) {
							del = getPreferredDelegate(modes);
							if(del == null) {
								del = getType().getPreferredDelegate(modes);
							}
							if(del != null) {
								delegate = del.getDelegate();
							}
							else {
								status = new Status(IStatus.CANCEL, DebugPlugin.getUniqueIdentifier(), DebugPlugin.ERROR, DebugCoreMessages.LaunchConfiguration_13, null);
								throw new CoreException(status);
							}
						}
						else {
							status = new Status(IStatus.CANCEL, DebugPlugin.getUniqueIdentifier(), DebugPlugin.ERROR, DebugCoreMessages.LaunchConfiguration_13, null);
							throw new CoreException(status);
						}
					}
					else {
						delegate = del.getDelegate();
					}
					break;
				}
			}

			ILaunchConfigurationDelegate2 delegate2 = null;
			if (delegate instanceof ILaunchConfigurationDelegate2) {
				delegate2 = (ILaunchConfigurationDelegate2) delegate;
			}
			// allow the delegate to provide a launch implementation
			ILaunch launch = null;
			if (delegate2 != null) {
				launch = delegate2.getLaunch(this, mode);
			}
			if (launch == null) {
				launch = new Launch(this, mode, null);
			} else {
				// ensure the launch mode is valid
				if (!mode.equals(launch.getLaunchMode())) {
					IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.ERROR,
							MessageFormat.format(DebugCoreMessages.LaunchConfiguration_14, mode, launch.getLaunchMode()), null);
					throw new CoreException(status);
				}
			}
			launch.setAttribute(DebugPlugin.ATTR_LAUNCH_TIMESTAMP, Long.toString(System.currentTimeMillis()));
			boolean captureOutput = getAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, true);
			if(!captureOutput) {
				launch.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, "false"); //$NON-NLS-1$
			} else {
				launch.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, null);
			}
			launch.setAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, getLaunchManager().getEncoding(this));
			if (register) {
				getLaunchManager().addLaunch(launch);
			}
		// perform initial pre-launch sanity checks
			lmonitor.subTask(DebugCoreMessages.LaunchConfiguration_8);

			if (delegate2 != null) {
				if (!(delegate2.preLaunchCheck(this, mode, lmonitor.split(1)))) {
					getLaunchManager().removeLaunch(launch);
					return launch;
				}
			}
			lmonitor.setWorkRemaining(22);
		// perform pre-launch build
			if (build) {
				lmonitor.subTask(DebugCoreMessages.LaunchConfiguration_7 + DebugCoreMessages.LaunchConfiguration_6);
				boolean tempbuild = build;
				if (delegate2 != null) {
					tempbuild = delegate2.buildForLaunch(this, mode, lmonitor.split(7));
				}
				if (tempbuild) {
					lmonitor.subTask(DebugCoreMessages.LaunchConfiguration_7 + DebugCoreMessages.LaunchConfiguration_5);
					ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, lmonitor.split(3));
				}
			}
			lmonitor.setWorkRemaining(12);
		// final validation
			lmonitor.subTask(DebugCoreMessages.LaunchConfiguration_4);
			if (delegate2 != null) {
				if (!(delegate2.finalLaunchCheck(this, mode, lmonitor.split(1)))) {
					getLaunchManager().removeLaunch(launch);
					return launch;
				}
			}
			lmonitor.setWorkRemaining(11);

			try {
				//initialize the source locator
				lmonitor.subTask(DebugCoreMessages.LaunchConfiguration_3);
				initializeSourceLocator(launch);
				lmonitor.worked(1);

				/* Launch the delegate */
				lmonitor.subTask(DebugCoreMessages.LaunchConfiguration_2);
				delegate.launch(this, mode, launch, lmonitor.split(10));
			} catch (CoreException e) {
				// if there was an exception, and the launch is empty, remove it
				if (!launch.hasChildren()) {
					getLaunchManager().removeLaunch(launch);
				}
				throw e;
			} catch (RuntimeException e) {
				// if there was a runtime exception, and the launch is empty, remove it
				if (!launch.hasChildren()) {
					getLaunchManager().removeLaunch(launch);
				}
				throw e;
			}
			if (lmonitor.isCanceled()) {
				getLaunchManager().removeLaunch(launch);
			}
			return launch;
		}
		finally {
			lmonitor.done();
		}
	}

	@Override
	public void migrate() throws CoreException {
		((LaunchConfigurationType)getType()).migrate(this);
	}

	/**
	 * Creates and returns a new error status based on
	 * the given message, code, and exception.
	 *
	 * @param message error message
	 * @param code error code
	 * @param e exception or <code>null</code>
	 * @return status
	 */
	protected IStatus newStatus(String message, int code, Throwable e) {
		return new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), code, message, e);
	}

	/**
	 * Sets the new name for this configuration.
	 *
	 * @param name the new name for this configuration
	 * @since 3.5
	 */
	protected void setName(String name) {
		fName = name;
	}

	/**
	 * Sets this configurations container or <code>null</code> if stored in the
	 * local metadata.
	 *
	 * @param container or <code>null</code>
	 * @since 3.5
	 */
	protected void setContainer(IContainer container) {
		fContainer = container;
	}

	@Override
	public boolean supportsMode(String mode) throws CoreException {
		return getType().supportsMode(mode);
	}

	@Override
	public boolean isReadOnly() {
		try {
			IFileStore fileStore = getFileStore();
			if (fileStore != null) {
				return fileStore.fetchInfo().getAttribute(EFS.ATTRIBUTE_READ_ONLY);
			}
		} catch (CoreException e) {
		}
		return true;
	}

	@Override
	public ILaunchDelegate getPreferredDelegate(Set<String> modes) throws CoreException {
		Map<String, String> delegates = getAttribute(LaunchConfiguration.ATTR_PREFERRED_LAUNCHERS, (Map<String, String>) null);
		if(delegates != null) {
			String id = delegates.get(modes.toString());
			if(id != null) {
				return getLaunchManager().getLaunchDelegate(id);
			}
		}
		return null;
	}

	@Override
	public String toString() {
		return getName();
	}

	@Override
	public ILaunchConfiguration getPrototype() throws CoreException {
		String memento = getAttribute(ATTR_PROTOTYPE, (String)null);
		if (memento != null) {
			LaunchConfiguration prototype = new LaunchConfiguration(memento);
			prototype.setIsPrototype(true);
			return prototype;
		}
		return null;
	}

	@Override
	public Collection<ILaunchConfiguration> getPrototypeChildren() throws CoreException {
		ILaunchConfiguration[] configurations = getLaunchManager().getLaunchConfigurations(getType());
		List<ILaunchConfiguration> proteges = new ArrayList<>();
		for (ILaunchConfiguration config : configurations) {
			if (this.equals(config.getPrototype())) {
				proteges.add(config);
			}
		}
		return proteges;
	}

	@Override
	public boolean isPrototype() {
		return fIsPrototype;
	}

	/**
	 * Set the prototype state of this configuration.
	 *
	 * @param isPrototype the prototype state.
	 *
	 * @since 3.12
	 */
	protected void setIsPrototype(boolean isPrototype) {
		fIsPrototype = isPrototype;
	}

	/**
	 * Check if the given file is a launch configuration prototype or not.
	 *
	 * @param file the given {@link IFile}.
	 * @return <code>true</code> if the given file is a launch configuration
	 *         prototype, false otherwise.
	 *
	 * @since 3.12
	 */
	protected static boolean isPrototype(IFile file) {
		if (ILaunchConfiguration.LAUNCH_CONFIGURATION_PROTOTYPE_FILE_EXTENSION.equals(file.getFileExtension())) {
			return true;
		}
		return false;
	}

	@Override
	public int getKind() throws CoreException {
		if (fIsPrototype) {
			return PROTOTYPE;
		}
		return CONFIGURATION;
	}

	@Override
	public boolean isAttributeModified(String attribute) throws CoreException {
		ILaunchConfiguration prototype = getPrototype();
		if (prototype != null) {
			Object prototypeValue = prototype.getAttributes().get(attribute);
			Object attributeValue = getAttributes().get(attribute);
			return !LaunchConfigurationInfo.compareAttribute(attribute, prototypeValue, attributeValue);
		}
		return false;
	}

	@Override
	public Set<String> getPrototypeVisibleAttributes() throws CoreException {
		return getInfo().getVisibleAttributes();
	}

	@Override
	public void setPrototypeAttributeVisibility(String attribute, boolean visible) throws CoreException {
		getInfo().setAttributeVisibility(attribute, visible);
	}
}
