/*******************************************************************************
 *  Copyright (c) 2000, 2018 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
 *     Sebastian Davids - Bug 137923
 *     Mohamed Hussein (Mentor Graphics) - Added s/getWarningMessage (Bug 386673)
 *     Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes
 *******************************************************************************/
package org.eclipse.debug.internal.ui.launchConfigurations;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.core.LaunchConfigurationWorkingCopy;
import org.eclipse.debug.internal.core.LaunchManager;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.WorkbenchJob;

import com.ibm.icu.text.MessageFormat;

/**
 * The dialog used to edit and launch launch configurations.
 */
public class LaunchConfigurationsDialog extends TitleAreaDialog implements ILaunchConfigurationDialog, IPropertyChangeListener {

	/**
	 * Keep track of the currently visible dialog instance
	 */
	private static ILaunchConfigurationDialog fgCurrentlyVisibleLaunchConfigurationDialog;
	/**
	 * Id for 'Launch' button.
	 */
	protected static final int ID_LAUNCH_BUTTON = IDialogConstants.CLIENT_ID + 1;

	/**
	 * Id for 'Close' button.
	 */
	protected static final int ID_CLOSE_BUTTON = IDialogConstants.CLIENT_ID + 2;
	/**
	 * Id for 'Cancel' button.
	 */
	protected static final int ID_CANCEL_BUTTON = IDialogConstants.CLIENT_ID + 3;

	/**
	 * The id for the 'No' button on the discard changes message box
	 * @since 3.3
	 */
	protected static final int ID_DISCARD_BUTTON = IDialogConstants.CLIENT_ID + 4;

	/**
	 * Constant specifying how wide this dialog is allowed to get (as a percentage of
	 * total available screen width) as a result of tab labels in the edit area.
	 */
	protected static final float MAX_DIALOG_WIDTH_PERCENT = 0.75f;
	/**
	 * Constant specifying how tall this dialog is allowed to get (as a percentage of
	 * total available screen height) as a result of preferred tab size.
	 */
	protected static final float MAX_DIALOG_HEIGHT_PERCENT = 0.65f;
	/**
	 * Size of this dialog if there is no preference specifying a size.
	 */
	protected static final Point DEFAULT_INITIAL_DIALOG_SIZE = new Point(800, 640);
	/**
	 * defines some default sash weights when we have a new workspace
	 * @since 3.2
	 */
	private static final int[] DEFAULT_SASH_WEIGHTS = new int[] {190, 610};
	/**
	 * Constant specifying that this dialog should be opened with the last configuration launched
	 * in the workspace selected.
	 */
	public static final int LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED = 2;
	/**
	 * Constant specifying that this dialog should be opened with the value specified via
	 * <code>setInitialSelection()</code> selected.
	 */
	public static final int LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION = 3;
	/**
	 * Constant specifying that a new launch configuration dialog was not opened.  Instead
	 * an existing launch configuration dialog was used.
	 */
	public static final int LAUNCH_CONFIGURATION_DIALOG_REUSE_OPEN = 4;
	/**
	 * defines the delimiter used in the persistence of the expanded state
	 * @since 3.2
	 */
	private static final String DELIMITER = ", "; //$NON-NLS-1$
	/**
	 * Specifies how this dialog behaves when opened.  Value is one of the
	 * 'LAUNCH_CONFIGURATION_DIALOG' constants defined in this class.
	 */
	private int fOpenMode = LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED;

	private boolean fIsShift = false;

	/**
	 * dialog settings
	 */
	private static final String DIALOG_SASH_WEIGHTS_1 = IDebugUIConstants.PLUGIN_ID + ".DIALOG_SASH_WEIGHTS_1"; //$NON-NLS-1$
	private static final String DIALOG_SASH_WEIGHTS_2 = IDebugUIConstants.PLUGIN_ID + ".DIALOG_SASH_WEIGHTS_2"; //$NON-NLS-1$
	private static final String DIALOG_EXPANDED_NODES = IDebugUIConstants.PLUGIN_ID + ".EXPANDED_NODES"; //$NON-NLS-1$

	/**
	 * Returns the currently visible dialog
	 * @return the currently visible launch dialog
	 */
	public static ILaunchConfigurationDialog getCurrentlyVisibleLaunchConfigurationDialog() {
		return fgCurrentlyVisibleLaunchConfigurationDialog;
	}
	/**
	 * Sets which launch dialog is currently the visible one
	 * @param dialog the dialog to set as the visible one
	 */
	public static void setCurrentlyVisibleLaunchConfigurationDialog(ILaunchConfigurationDialog dialog) {
		fgCurrentlyVisibleLaunchConfigurationDialog = dialog;
	}

	/**
	 * widgets
	 */
	private Control fLastControl;
	private Composite fButtonComp;
	private SashForm fSashForm;
	private LaunchConfigurationView fLaunchConfigurationView;
	private LaunchConfigurationTabGroupViewer fTabViewer;
	private ProgressMonitorPart fProgressMonitorPart;
	private LaunchGroupExtension fGroup;
	private Image fBannerImage;

	/**
	 * When this dialog is opened in <code>LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION</code>
	 * mode, this specifies the selection that is initially shown in the dialog.
	 */
	private IStructuredSelection fInitialSelection;

	/**
	 * The status to open the dialog on, or <code>null</code> if none.
	 */
	private IStatus fInitialStatus;

	/**
	 * The number of 'long-running' operations currently taking place in this dialog
	 */
	private long fActiveRunningOperations = 0;

	/**
	 * Double-click action
	 */
	private IAction fDoubleClickAction;

	/**
	 * Filters for the LCD
	 * @since 3.2
	 */
	private ClosedProjectFilter fClosedProjectFilter;
	private DeletedProjectFilter fDeletedProjectFilter;
	private LaunchConfigurationTypeFilter fLCTFilter;
	private WorkingSetsFilter fWorkingSetsFilter;

	/**
	 * set of reserved names that should not be considered when generating a new name for a launch configuration
	 */
	protected Set<String> fReservedNames = null;

	/**
	 * Whether to set default values when opened
	 * @since 3.6
	 */
	private boolean fSetDefaultOnOpen = false;

	/**
	 * Whether in the process of setting the input to the tab viewer
	 */
	private boolean fSettingInput = false;

	/**
	 * Constructs a new launch configuration dialog on the given
	 * parent shell.
	 *
	 * @param shell the parent shell
	 * @param group the group of launch configuration to display
	 */
	public LaunchConfigurationsDialog(Shell shell, LaunchGroupExtension group) {
		super(shell);
		setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
		setLaunchGroup(group);
	}

	/**
	 * Adds content to the dialog area
	 *
	 * @param dialogComp
	 */
	protected void addContent(Composite dialogComp) {
		GridData gd;
		Composite topComp = new Composite(dialogComp, SWT.NONE);
		gd = new GridData(GridData.FILL_BOTH);
		topComp.setLayoutData(gd);
		GridLayout topLayout = new GridLayout(2, false);
		topLayout.marginHeight = 5;
		topLayout.marginWidth = 5;
		topComp.setLayout(topLayout);

		// Set the things that TitleAreaDialog takes care of
		setTitle(LaunchConfigurationsMessages.LaunchConfigurationDialog_Create__manage__and_run_launch_configurations_8);
		setMessage(LaunchConfigurationsMessages.LaunchConfigurationDialog_Ready_to_launch_2);
		setModeLabelState();

		// Create the SashForm that contains the selection area on the left,
		// and the edit area on the right
		gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 2;
		SashForm sash = new SashForm(topComp, SWT.SMOOTH);
		sash.setOrientation(SWT.HORIZONTAL);
		sash.setLayoutData(gd);
		sash.setFont(dialogComp.getFont());
		sash.setVisible(true);
		fSashForm = sash;

		// Build the launch configuration selection area and put it into the composite.
		Control launchConfigSelectionArea = createLaunchConfigurationSelectionArea(fSashForm);
		gd = new GridData(GridData.FILL_VERTICAL);
		launchConfigSelectionArea.setLayoutData(gd);

		// Build the launch configuration edit area and put it into the composite.
		Composite editAreaComp = createLaunchConfigurationEditArea(fSashForm);
		gd = new GridData(GridData.FILL_BOTH);
		editAreaComp.setLayoutData(gd);

		dialogComp.layout(true);
		applyDialogFont(dialogComp);
	}

	/**
	 * Handle the 'close' & 'launch' buttons here, all others are handled
	 * in <code>Dialog</code>
	 *
	 * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
	 */
	@Override
	protected void buttonPressed(int buttonId) {
		if (buttonId == ID_LAUNCH_BUTTON) {
			handleLaunchPressed();
		}
		else if (buttonId == ID_CLOSE_BUTTON) {
			handleClosePressed();
		}
		else {
			super.buttonPressed(buttonId);
		}
	}

	/**
	 * Return whether the current configuration should be saved or discarded.  This involves determining
	 * if it is dirty, and if it is, asking the user what to do.
	 *
	 * @return if we can discard the current config or not
	 */
	protected int shouldSaveCurrentConfig() {
		if (fTabViewer.isDirty()) {
			if (fTabViewer.canSave()) {
				return showSaveChangesDialog();
			}
			return showUnsavedChangesDialog();
		}
		return IDialogConstants.NO_ID;
	}

	@Override
	public boolean close() {
	    if (!isSafeToClose()) {
	        return false;
	    }
	    persistSashWeights();
	    persistExpansion();
		setCurrentlyVisibleLaunchConfigurationDialog(null);
		fTabViewer.dispose();
		if (fLaunchConfigurationView != null) {
			fLaunchConfigurationView.dispose();
		}
		DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		boolean result = super.close();
		getBannerImage().dispose();
		return result;
	}

	/**
	 * Sets the title for the dialog, and establishes the help context.
	 *
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell);
	 */
	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText(getShellTitle());
	}

	@Override
	public void create() {
		super.create();
		if (fTabViewer.getInput() == null) {
			fTabViewer.inputChanged(null);
		}
	}

	@Override
	protected Control createButtonBar(Composite parent) {
		Font font = parent.getFont();
		Composite composite = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		layout.marginLeft = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		composite.setFont(font);
		// create help control if needed
        if (isHelpAvailable()) {
        	createHelpControl(composite);
        }
		Composite monitorComposite = new Composite(composite, SWT.NULL);
		layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		layout.numColumns = 2;
		monitorComposite.setLayout(layout);
		monitorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		GridLayout pmLayout = new GridLayout();
		fProgressMonitorPart= new ProgressMonitorPart(monitorComposite, pmLayout, true);
		fProgressMonitorPart.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		fProgressMonitorPart.setFont(font);
		monitorComposite.setVisible(false);

		/*
		 * Create the rest of the button bar, but tell it not to
		 * create a help button (we've already created it).
		 */
		boolean helpAvailable = isHelpAvailable();
		setHelpAvailable(false);
		fButtonComp = (Composite) super.createButtonBar(composite);
		setHelpAvailable(helpAvailable);
		return composite;
	}

	/**
	 *
	 * @param buttonId
	 */
	protected void launchButtonPressed(int buttonId) {
		if (buttonId == ID_LAUNCH_BUTTON) {
			handleLaunchPressed();
		} else if (buttonId == ID_CLOSE_BUTTON) {
			handleClosePressed();
		} else {
			super.buttonPressed(buttonId);
		}
	}


	/**
	 * A launch configuration dialog overrides this method
	 * to create a custom set of buttons in the button bar.
	 * This dialog has 'Launch' and 'Cancel'
	 * buttons.
	 *
	 * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		Button button = createButton(parent, ID_LAUNCH_BUTTON, getLaunchButtonText(), true);
        button.setEnabled(false);
		Listener[] listeners = button.getListeners(SWT.Selection);
		for (Listener listener : listeners) {
			button.removeListener(SWT.Selection, listener);
		}
		listeners = button.getListeners(SWT.DefaultSelection);
		for (Listener listener : listeners) {
			button.removeListener(SWT.DefaultSelection, listener);
		}

		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				setShift(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
				handleLaunchPressed();
			}
		});
		createButton(parent, ID_CLOSE_BUTTON, LaunchConfigurationsMessages.LaunchConfigurationDialog_Close_1, false);
	}

	@Override
	protected Control createContents(Composite parent) {
		Control contents = super.createContents(parent);
		initializeContent();
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), getHelpContextId());
		return contents;
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite dialogComp = (Composite)super.createDialogArea(parent);
		addContent(dialogComp);
		if(fLaunchConfigurationView != null) {
			fLaunchConfigurationView.updateFilterLabel();
		}
		return dialogComp;
	}

	/**
	 * Creates the launch configuration edit area of the dialog.
	 * This area displays the name of the launch configuration
	 * currently being edited, as well as a tab folder of tabs
	 * that are applicable to the launch configuration.
	 *
	 * @return the composite used for launch configuration editing
	 */
	protected Composite createLaunchConfigurationEditArea(Composite parent) {
		setTabViewer(new LaunchConfigurationTabGroupViewer(parent, this));
		return (Composite)fTabViewer.getControl();
	}

	/**
	 * Creates all of the actions for the toolbar
	 * @param toolbar
	 * @since 3.2
	 */
	protected void createToolbarActions(ToolBarManager tmanager) {
		tmanager.add(getNewAction());
		tmanager.add(getNewPrototypeAction());
		tmanager.add(getExportAction());
		tmanager.add(getDuplicateAction());
		tmanager.add(getDeleteAction());
		tmanager.add(new Separator());
		tmanager.add(getCollapseAllAction());
		tmanager.add(getFilterAction());
		tmanager.update(true);
		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
	}

	protected void setShift(boolean isShift) {
		fIsShift = isShift;
	}
	/**
	 * Creates the launch configuration selection area of the dialog.
	 * This area displays a tree of launch configurations that the user
	 * may select, and allows users to create new configurations, and
	 * delete and duplicate existing configurations.
	 *
	 * @return the composite used for launch configuration selection area
	 */
	protected Control createLaunchConfigurationSelectionArea(Composite parent) {
        Composite comp = new Composite(parent, SWT.FLAT);
        GridLayout gridLayout = new GridLayout(1, false);
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
        comp.setLayout(gridLayout);
        comp.setLayoutData(new GridData(GridData.FILL_BOTH));

        ViewForm viewForm = new ViewForm(comp, SWT.FLAT | SWT.BORDER);
        ToolBarManager toolBarManager= new ToolBarManager(SWT.FLAT);
        ToolBar toolBar = toolBarManager.createControl(viewForm);
        toolBar.setBackground(parent.getBackground());
        viewForm.setTopLeft(toolBar);
        viewForm.setLayoutData(new GridData(GridData.FILL_BOTH));

        Composite viewFormContents = new Composite(viewForm, SWT.FLAT);
        gridLayout = new GridLayout();
        gridLayout.marginHeight = 5;
        gridLayout.marginWidth = 5;
        viewFormContents.setLayout(gridLayout);
        viewFormContents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
		fLaunchConfigurationView = new LaunchConfigurationView(getLaunchGroup(), createViewerFilters());
		fLaunchConfigurationView.createLaunchDialogControl(viewFormContents);
		Text filterText = fLaunchConfigurationView.getFilteringTextControl();
		if (filterText != null){
			filterText.setFocus();
		}

	//create toolbar actions, we reuse the actions from the view so we wait until after
	//the view is created to add them to the toolbar
		createToolbarActions(toolBarManager);
		fDoubleClickAction = new Action() {
			@Override
			public void run() {
				runInternal(false);
			}

			@Override
			public void runWithEvent(Event event) {
				runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
			}

			void runInternal(boolean isShift) {
				IStructuredSelection selection = (IStructuredSelection)fLaunchConfigurationView.getViewer().getSelection();
				Object target = selection.getFirstElement();
				if (target instanceof ILaunchConfiguration) {
					if (fTabViewer.canLaunch() & fTabViewer.canLaunchWithModes() & !fTabViewer.hasDuplicateDelegates()) {
						setShift(isShift);
						handleLaunchPressed();
					}
				} else {
					getNewAction().run();
				}
			}
		};
		fLaunchConfigurationView.setAction(IDebugView.DOUBLE_CLICK_ACTION, fDoubleClickAction);
		Viewer viewer = fLaunchConfigurationView.getViewer();

		Control control = viewer.getControl();
		GridData gd = new GridData(GridData.FILL_BOTH);
		control.setLayoutData(gd);
        viewForm.setContent(viewFormContents);
		AbstractLaunchConfigurationAction.IConfirmationRequestor requestor = new AbstractLaunchConfigurationAction.IConfirmationRequestor() {
			@Override
			public boolean getConfirmation() {
				int status = shouldSaveCurrentConfig();
				if(status == IDialogConstants.YES_ID) {
					fTabViewer.handleApplyPressed();
					return true;
				}
				else if(status == IDialogConstants.NO_ID) {
					fTabViewer.handleRevertPressed();
					return true;
				}
				return false;
			}
		};
		getDuplicateAction().setConfirmationRequestor(requestor);
		getExportAction().setConfirmationRequestor(requestor);
		getNewAction().setConfirmationRequestor(requestor);
		getNewPrototypeAction().setConfirmationRequestor(requestor);
		getLinkPrototypeAction().setConfirmationRequestor(requestor);
		getUnlinkPrototypeAction().setConfirmationRequestor(requestor);
		getResetWithPrototypeValuesAction().setConfirmationRequestor(requestor);
		((StructuredViewer) viewer).addPostSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				handleLaunchConfigurationSelectionChanged(event);
				getNewAction().setEnabled(getNewAction().isEnabled());
				getNewPrototypeAction().setEnabled(getNewPrototypeAction().isEnabled());
				getDeleteAction().setEnabled(getDeleteAction().isEnabled());
				getExportAction().setEnabled(getExportAction().isEnabled());
				getDuplicateAction().setEnabled(getDuplicateAction().isEnabled());
				getLinkPrototypeAction().setEnabled(getLinkPrototypeAction().isEnabled());
				getUnlinkPrototypeAction().setEnabled(getUnlinkPrototypeAction().isEnabled());
				getResetWithPrototypeValuesAction().setEnabled(getResetWithPrototypeValuesAction().isEnabled());
			}
		});
		return comp;
	}

	/**
	 * Create the filters to be initially applied to the viewer.
	 * The initial filters are based on the persisted preferences
	 * @return the array of initial filters
	 * @since 3.2
	 */
	private ViewerFilter[] createViewerFilters() {
		ArrayList<ViewerFilter> filters = new ArrayList<>();
		fClosedProjectFilter = new ClosedProjectFilter();
		if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_CLOSED)) {
			filters.add(fClosedProjectFilter);
		}
		fDeletedProjectFilter = new DeletedProjectFilter();
		if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_DELETED)) {
			filters.add(fDeletedProjectFilter);
		}
		fLCTFilter = new LaunchConfigurationTypeFilter();
		if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES)) {
			filters.add(fLCTFilter);
		}
		fWorkingSetsFilter = new WorkingSetsFilter();
		if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_WORKING_SETS)) {
			filters.add(fWorkingSetsFilter);
		}
		return filters.toArray(new ViewerFilter[filters.size()]);
	}

	/**
	 * Set the initial selection in the tree.
	 */
	public void doInitialTreeSelection() {
		fLaunchConfigurationView.getViewer().setSelection(fInitialSelection);
	}

	@Override
	public String generateName(String name) {
		if (name == null) {
			return getLaunchManager().generateLaunchConfigurationName(IInternalDebugCoreConstants.EMPTY_STRING);
		}
		return getLaunchManager().generateLaunchConfigurationName(name);
	}

	/**
	 * Generates and returns a unique name using the specified name as a prefix in the event
	 * the specified name already exists or is contained in the set of reserved names.
	 * @param name the name to use as a prefix for generating a new name
	 * @param reservednames a listing of names that should be considered as 'taken' and cannot be generated
	 * by this method
	 * @return a new name based on the specified name.
	 *
	 * @since 3.3
	 */
	public String generateName(String name, Set<String> reservednames) {
		if(name == null) {
			return ((LaunchManager) getLaunchManager()).generateUniqueLaunchConfigurationNameFrom(IInternalDebugCoreConstants.EMPTY_STRING, reservednames);
		}
		return ((LaunchManager)getLaunchManager()).generateUniqueLaunchConfigurationNameFrom(name, reservednames);
	}

	@Override
	public ILaunchConfigurationTab getActiveTab() {
		return fTabViewer.getActiveTab();
	}

	/**
	 * Returns the banner image to display in the title area
	 */
	protected Image getBannerImage() {
		if (fBannerImage == null) {
			ImageDescriptor descriptor = getLaunchGroup().getBannerImageDescriptor();
			if (descriptor != null) {
				fBannerImage = descriptor.createImage();
			}
		}
		return fBannerImage;
	}

	/**
	 * Gets the delete menu action
	 *
	 * @return the delete menu action
	 */
	protected AbstractLaunchConfigurationAction getDeleteAction() {
		return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(DeleteLaunchConfigurationAction.ID_DELETE_ACTION);
	}

	/**
	 * Gets the filter action
	 * @return the filter menu action
	 * @since 3.2
	 */
	protected IAction getFilterAction() {
		return fLaunchConfigurationView.getAction(FilterLaunchConfigurationAction.ID_FILTER_ACTION);
	}

	/**
	 * Gets the collapse all action
	 * @return the collapse all action
	 * @since 3.2
	 */
	protected IAction getCollapseAllAction() {
		return fLaunchConfigurationView.getAction(CollapseAllLaunchConfigurationAction.ID_COLLAPSEALL_ACTION);
	}

	 /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
     * @since 3.2
     */
    @Override
	protected IDialogSettings getDialogBoundsSettings() {
    	return getDialogSettings();
    }

    @Override
	protected int getDialogBoundsStrategy() {
    	return DIALOG_PERSISTSIZE;
    }

	/**
	 * Returns the dialog settings for this dialog. Subclasses should override
	 * <code>getDialogSettingsSectionName()</code>.
	 *
	 * @return IDialogSettings
	 */
	protected IDialogSettings getDialogSettings() {
		IDialogSettings settings = DebugUIPlugin.getDefault().getDialogSettings();
		IDialogSettings section = settings.getSection(getDialogSettingsSectionName());
		if (section == null) {
			section = settings.addNewSection(getDialogSettingsSectionName());
		}
		return section;
	}

	/**
	 * Returns the name of the section that this dialog stores its settings in
	 *
	 * @return String
	 */
	protected String getDialogSettingsSectionName() {
		return IDebugUIConstants.PLUGIN_ID + ".LAUNCH_CONFIGURATIONS_DIALOG_SECTION"; //$NON-NLS-1$
	}

	/**
	 * Gets the current display
	 *
	 * @return the display
	 */
	protected Display getDisplay() {
		Shell shell = getShell();
		if (shell != null) {
			return shell.getDisplay();
		}
		return DebugUIPlugin.getStandardDisplay();
	}

  	/**
  	 * Gets the duplicate menu action
  	 *
  	 * @return the duplicate menu action
  	 */
  	protected AbstractLaunchConfigurationAction getDuplicateAction() {
		return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(DuplicateLaunchConfigurationAction.ID_DUPLICATE_ACTION);
	}

	/**
	 * Gets the export menu action
	 *
	 * @return the export menu action
	 */
	protected AbstractLaunchConfigurationAction getExportAction() {
		return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(ExportLaunchConfigurationAction.ID_EXPORT_ACTION);
	}

	/**
	 * Gets the help context id
	 *
	 * @return the help context id
	 */
	protected String getHelpContextId() {
		return IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG;
	}

 	/**
	 * Returns the status the dialog was opened on or <code>null</code> if none.
	 *
	 * @return IStatus
	 */
	protected IStatus getInitialStatus() {
		return fInitialStatus;
	}

 	/**
	 * Return the last launched configuration in the workspace.
	 *
	 * @return the last launched configuration
	 */
	protected ILaunchConfiguration getLastLaunchedWorkbenchConfiguration() {
		return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLastLaunch(getLaunchGroup().getIdentifier());
	}

 	/**
	 * Returns the appropriate text for the launch button - run or debug.
	 *
	 * @return the launch button text
	 */
	protected String getLaunchButtonText() {
		return DebugPlugin.getDefault().getLaunchManager().getLaunchMode(getMode()).getLabel();
	}

 	/**
	 * Returns the launch group being displayed.
	 *
	 * @return launch group
	 */
	public LaunchGroupExtension getLaunchGroup() {
		return fGroup;
	}

 	@Override
	public String getMode() {
 		return getLaunchGroup().getMode();
 	}

	/**
	 * Gets the new menu action
	 *
	 * @return the new menu action
	 */
	protected AbstractLaunchConfigurationAction getNewAction() {
		return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(CreateLaunchConfigurationAction.ID_CREATE_ACTION);
	}

	/**
	 * Gets the new prototype menu action
	 *
	 * @return the new prototype menu action
	 *
	 * @since 3.13
	 */
	protected AbstractLaunchConfigurationAction getNewPrototypeAction() {
		return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(CreateLaunchConfigurationPrototypeAction.ID_CREATE_PROTOTYPE_ACTION);
	}

	/**
	 * Gets the link prototype menu action
	 *
	 * @return the link prototype menu action
	 *
	 * @since 3.13
	 */
	protected AbstractLaunchConfigurationAction getLinkPrototypeAction() {
		return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(LinkPrototypeAction.ID_LINK_PROTOTYPE_ACTION);
	}

	/**
	 * Gets the unlink prototype menu action
	 *
	 * @return the unlink prototype menu action
	 *
	 * @since 3.13
	 */
	protected AbstractLaunchConfigurationAction getUnlinkPrototypeAction() {
		return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(UnlinkPrototypeAction.ID_UNLINK_PROTOTYPE_ACTION);
	}

	/**
	 * Gets the reset with prototype values menu action
	 *
	 * @return the reset with prototype values menu action
	 *
	 * @since 3.13
	 */
	protected AbstractLaunchConfigurationAction getResetWithPrototypeValuesAction() {
		return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(ResetWithPrototypeValuesAction.ID_RESET_WITH_PROTOTYPE_VALUES_ACTION);
	}

	/**
	 * Returns the reserved name set (if there is one), <code>null</code> otherwise
	 * @return the reserved name set or <code>null</code>
	 * @since 3.3
	 *
	 */
	public Set<String> getReservedNameSet() {
		return fReservedNames;
	}

	/**
	 * returns the open mode
	 *
	 * @return the open mode
	 */
	protected int getOpenMode() {
		return fOpenMode;
	}

	public Object getSelectedPage() {
		return getActiveTab();
	}

	/**
	 * Returns the title of the shell
	 * @return the shell title
	 */
	protected String getShellTitle() {
		String title = null;
		if(getLaunchGroup() != null) {
			title = MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationsDialog_configurations, new Object[] { DebugUIPlugin.removeAccelerators(getLaunchGroup().getLabel()) });
		}
		if (title == null) {
			title = LaunchConfigurationsMessages.LaunchConfigurationDialog_Launch_Configurations_18;
		}
		return title;
	}

	/**
 	 * Returns the current tab group
 	 *
 	 * @return the current tab group, or <code>null</code> if none
 	 */
 	public ILaunchConfigurationTabGroup getTabGroup() {
 		if (fTabViewer != null) {
 			return fTabViewer.getTabGroup();
 		}
 		return null;
 	}

 	@Override
	public ILaunchConfigurationTab[] getTabs() {
 		if (getTabGroup() == null) {
 			return null;
 		}
 		return getTabGroup().getTabs();
 	}

	/**
	 * Returns the viewer used to display the tabs for a launch configuration.
	 *
	 * @return LaunchConfigurationTabGroupViewer
	 */
	public LaunchConfigurationTabGroupViewer getTabViewer() {
		return fTabViewer;
	}

	/**
	 * Notification the 'Close' button has been pressed.
	 */
	protected void handleClosePressed() {
		if(fTabViewer.canSave()) {
			int status = shouldSaveCurrentConfig();
			if(status != IDialogConstants.CANCEL_ID) {
				if(status != ID_DISCARD_BUTTON) {
					if(status == IDialogConstants.YES_ID) {
						fTabViewer.handleApplyPressed();
					}
					cancelPressed();
				}
			}
		}
		else {
			cancelPressed();
		}
	}

	/**
	 * Notification that selection has changed in the launch configuration tree.
	 * <p>
	 * If the currently displayed configuration is not saved,
	 * prompt for saving before moving on to the new selection.
	 * </p>
	 *
	 * @param event selection changed event
	 */
 	protected void handleLaunchConfigurationSelectionChanged(SelectionChangedEvent event) {
 		Object input = fTabViewer.getInput();
 		Object newInput = null;
		IStructuredSelection selection = event.getStructuredSelection();
 		if (selection.size() == 1) {
			newInput = selection.getFirstElement();
 		}
 		if (!isEqual(input, newInput)) {
 			ILaunchConfiguration original = fTabViewer.getOriginal();
 	 		if (original != null && newInput == null && getLaunchManager().getMovedTo(original) != null) {
 				return;
 			}
 			boolean deleted = false;
 			if (original != null) {
 				deleted = !original.exists();
 			}
			boolean renamed = false;
			if (newInput instanceof ILaunchConfiguration) {
				renamed = getLaunchManager().getMovedFrom((ILaunchConfiguration)newInput) != null;
			}
			try {
				fSettingInput = true;
	 			if (fTabViewer.canSave() && fTabViewer.isDirty() && !deleted && !renamed) {
	 				if(fLaunchConfigurationView != null) {
	 					fLaunchConfigurationView.setAutoSelect(false);
	 				}
	 				int ret = showUnsavedChangesDialog();
	 				if(ret == IDialogConstants.YES_ID) {
	 					fTabViewer.handleApplyPressed();
						ILaunchConfigurationTab[] tabs = getTabs();
						if (tabs != null) {
							for (ILaunchConfigurationTab tab : tabs) {
								tab.postApply();
							}
						}
	 					fTabViewer.setInput(newInput);
	 				}
					else if(ret == IDialogConstants.NO_ID) {
						fTabViewer.handleRevertPressed();
						fTabViewer.setInput(newInput);
					}
					else {
						fLaunchConfigurationView.getViewer().setSelection(new StructuredSelection(input));
					}
	 				fLaunchConfigurationView.setAutoSelect(true);
	  			}
	 			else {
	 				fTabViewer.setInput(newInput);
	 				if(fTabViewer.isDirty()) {
	 					fTabViewer.handleApplyPressed();
	 				}
	 			}
			} finally {
				fSettingInput = false;
				updateButtons();
				updateMessage();
			}
 			if(getShell() != null && getShell().isVisible()) {
 				resize();
 			}
 		}
  	}

	/**
	 * Notification the 'launch' button has been pressed. Save and launch.
	 *
	 */
	protected void handleLaunchPressed() {
		ILaunchConfiguration config = fTabViewer.getOriginal();
		if (fTabViewer.isDirty() && fTabViewer.canSave()) {
			config = fTabViewer.handleApplyPressed();
		}
		if(config != null) {
			close();
			DebugUITools.launch(config, getMode(), fIsShift);
		}
		setShift(false);
	}

	/**
	 * Consult a status handler for the given status, if any. The status handler
	 * is passed this launch config dialog as an argument.
	 *
	 * @param status the status to be handled
	 */
	public void handleStatus(IStatus status) {
		IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(status);
		if (handler != null) {
			try {
				handler.handleStatus(status, this);
				return;
			}
			catch (CoreException e) {status = e.getStatus();}
		}
		// if no handler, or handler failed, display error/warning dialog
		String title = null;
		switch (status.getSeverity()) {
			case IStatus.ERROR:
				title = LaunchConfigurationsMessages.LaunchConfigurationsDialog_Error_1;
				break;
			case IStatus.WARNING:
				title = LaunchConfigurationsMessages.LaunchConfigurationsDialog_Warning_2;
				break;
			default:
				title = LaunchConfigurationsMessages.LaunchConfigurationsDialog_Information_3;
				break;
		}
		ErrorDialog.openError(getShell(), title, null, status);
	}

	@Override
	protected void initializeBounds() {
		IDialogSettings settings = getDialogSettings();
		if (fSashForm != null) {
			int w1, w2;
			try {
				w1 = settings.getInt(DIALOG_SASH_WEIGHTS_1);
				if(w1 < 10) {
					w1 = DEFAULT_SASH_WEIGHTS[0];
				}
				w2 = settings.getInt(DIALOG_SASH_WEIGHTS_2);
				if(w2 < 10) {
					w2 = DEFAULT_SASH_WEIGHTS[1];
				}
			}
			catch(NumberFormatException nfe) {
				w1 = DEFAULT_SASH_WEIGHTS[0];
				w2 = DEFAULT_SASH_WEIGHTS[1];
			}
			fSashForm.setWeights(new int[] {w1, w2});
		}
		super.initializeBounds();
	}

	@Override
	protected Point getInitialSize() {
		try {
			getDialogSettings().getInt("DIALOG_HEIGHT"); //$NON-NLS-1$
			return super.getInitialSize();
		}
		catch(NumberFormatException nfe) {
			return DEFAULT_INITIAL_DIALOG_SIZE;
		}
	}

	/**
	 * Sets the default values for the given {@link LaunchConfigurationWorkingCopy}
	 * @param wc
	 * @since 3.6
	 */
	protected void doSetDefaults(ILaunchConfigurationWorkingCopy wc) {
		try {
			ILaunchConfigurationTabGroup tabGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(wc, getMode());
			// this only works because this action is only present when the dialog is open
			ILaunchConfigurationDialog dialog = LaunchConfigurationsDialog.getCurrentlyVisibleLaunchConfigurationDialog();
			tabGroup.createTabs(dialog, dialog.getMode());
			ILaunchConfigurationTab[] tabs = tabGroup.getTabs();
			for (int i = 0; i < tabs.length; i++) {
				tabs[i].setLaunchConfigurationDialog(dialog);
			}
			tabGroup.setDefaults(wc);
			tabGroup.dispose();
		} catch (CoreException e) {
			DebugUIPlugin.log(e.getStatus());
		}
	}

	/**
	 * Performs initialization of the content by setting the initial tree selection
	 */
	protected void initializeContent() {
		if(fSetDefaultOnOpen) {
			try {
				Object o = fInitialSelection.getFirstElement();
				if(o instanceof ILaunchConfigurationWorkingCopy) {
					ILaunchConfigurationWorkingCopy wc = (ILaunchConfigurationWorkingCopy) o;
					doSetDefaults(wc);
					setInitialSelection(new StructuredSelection(wc.doSave()));
				}
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
			}
		}
		doInitialTreeSelection();

		IStatus status = getInitialStatus();
		if (status != null) {
			handleStatus(status);
		}
		restoreExpansion();
	}

	/**
	 * Compares two objects to determine their equality
	 *
	 * @param o1 the first object
	 * @param o2 the object to compare to object one
	 * @return true if they are equal, false if object 1 is null, the result of o1.equals(o2) otherwise
	 */
	protected boolean isEqual(Object o1, Object o2) {
  		if (o1 == o2) {
  			return true;
  		} else if (o1 == null) {
  			return false;
  		} else {
  			return o1.equals(o2);
  		}
  	}

	/**
	 * Returns whether the dialog can be closed
	 *
	 * @return whether the dialog can be closed
	 */
	protected boolean isSafeToClose() {
	    return fActiveRunningOperations == 0;
	}

	/**
	 * Determine the initial configuration for this dialog.
	 * Open the dialog in the mode set using #setOpenMode(int) and return one of
	 * <code>Window. OK</code> or <code>Window.CANCEL</code>.
	 *
	 * @see org.eclipse.jface.window.Window#open()
	 * @return the int status of opening the dialog
	 */
	@Override
	public int open() {
		int mode = getOpenMode();
		setCurrentlyVisibleLaunchConfigurationDialog(this);
		if (mode == LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED) {
			ILaunchConfiguration lastLaunchedConfig = getLastLaunchedWorkbenchConfiguration();
			if (lastLaunchedConfig != null) {
				setInitialSelection(new StructuredSelection(lastLaunchedConfig));
			}
		}
		return super.open();
	}

	/**
	 * saves which of the nodes are expanded at the time the dialog is closed
	 * @since 3.2
	 */
	protected void persistExpansion() {
		if(fLaunchConfigurationView != null) {
			IDialogSettings settings = getDialogSettings();
			TreeItem[] items = fLaunchConfigurationView.getTreeViewer().getTree().getItems();
			String value = settings.get(DIALOG_EXPANDED_NODES);
			if(value == null) {
				value = IInternalDebugCoreConstants.EMPTY_STRING;
			}
			ArrayList<String> list = new ArrayList<>();
			String[] persisted = value.split(DELIMITER);
			for(int i = 0; i < persisted.length; i++) {
				list.add(persisted[i]);
			}
			String type = IInternalDebugCoreConstants.EMPTY_STRING;
			//if the item is not in the list and is expanded add it, otherwise if it
			//is not expanded do a remove...either way for the else we query the list
			for(int i = 0; i < items.length; i++) {
				type = ((ILaunchConfigurationType)items[i].getData()).getIdentifier();
				if(!list.contains(type) & items[i].getExpanded()) {
					list.add(type);
				}
				else if(!items[i].getExpanded()) {
					list.remove(type);
				}
			}
			value = IInternalDebugCoreConstants.EMPTY_STRING;
			//build the preference string
			for (Iterator<String> iter = list.iterator(); iter.hasNext();) {
				value += iter.next() + DELIMITER;
			}
			settings.put(DIALOG_EXPANDED_NODES, value);
		}
	}

	/**
	 * Restore the original expansion state of the nodes in the viewer
	 * @since 3.2
	 */
	protected void restoreExpansion() {
		if(fLaunchConfigurationView != null) {
			IDialogSettings settings = getDialogSettings();
			String value = settings.get(DIALOG_EXPANDED_NODES);
			if(value != null) {
				String[] nodes = value.split(DELIMITER);
				TreeItem[] items = fLaunchConfigurationView.getTreeViewer().getTree().getItems();
				HashSet<Object> toexpand = new HashSet<>();
				// if we have a selection make sure it is expanded
				if(fInitialSelection != null && !fInitialSelection.isEmpty()) {
					Object obj = fInitialSelection.getFirstElement();
					if(obj instanceof ILaunchConfigurationType) {
						toexpand.add(obj);
					}
					else if(obj instanceof ILaunchConfiguration) {
						try {
							toexpand.add(((ILaunchConfiguration) obj).getType());
						}
						catch (CoreException e) {DebugUIPlugin.log(e);}
					}
				}
				for(int i = 0; i < nodes.length; i++) {
					for(int k = 0; k < items.length; k++) {
						ILaunchConfigurationType type = (ILaunchConfigurationType)items[k].getData();
						if(type.getIdentifier().equals(nodes[i])) {
							toexpand.add(type);
						}
					}
				}
				fLaunchConfigurationView.getTreeViewer().setExpandedElements(toexpand.toArray());
			}
		}
	}

	/**
	 * Save the current sash weights
	 */
	protected void persistSashWeights() {
		IDialogSettings settings = getDialogSettings();
		if (fSashForm != null) {
			int[] sashWeights = fSashForm.getWeights();
			settings.put(DIALOG_SASH_WEIGHTS_1, (sashWeights[0] < 10 ? DEFAULT_SASH_WEIGHTS[0] : sashWeights[0]));
			settings.put(DIALOG_SASH_WEIGHTS_2, (sashWeights[1] < 10 ? DEFAULT_SASH_WEIGHTS[1] : sashWeights[1]));
		}
	}

	/**
	 * Update buttons and message.
	 */
	protected void refreshStatus() {
		updateMessage();
		updateButtons();
	}

	/**
	 * Refresh the launch configurations' tree viewer
	 *
	 * @since 3.13
	 */
	public void refreshLaunchConfigurationView() {
		fLaunchConfigurationView.getTreeViewer().refresh();
	}

	/**
	 * resize the dialog to show all relevant content
	 */
	protected void resize() {
 		if(getTabGroup() != null) {
			Point shell = getShell().getSize();
 			int maxx = (int)(getDisplay().getBounds().width * MAX_DIALOG_WIDTH_PERCENT),
				maxy = (int) (getDisplay().getBounds().height * MAX_DIALOG_HEIGHT_PERCENT);
 			maxx = (maxx < DEFAULT_INITIAL_DIALOG_SIZE.x ? DEFAULT_INITIAL_DIALOG_SIZE.x : maxx);
 			maxy = (maxy < DEFAULT_INITIAL_DIALOG_SIZE.y ? DEFAULT_INITIAL_DIALOG_SIZE.y : maxy);
 			Point psize = getShell().computeSize(SWT.DEFAULT, maxy);
 			if((psize.x > maxx ? maxx : psize.x) > shell.x || (psize.y > maxy ? maxy : psize.y) > shell.y) {
				setShellSize(Math.min(psize.x, maxx), Math.min(psize.y, maxy));
				constrainShellSize();
 			}
		}
	}

	@Override
	public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
		if (getShell() != null && getShell().isVisible()) {
			// Save focus control
			fLastControl = getShell().getDisplay().getFocusControl();
			if (fLastControl != null && fLastControl.getShell() != getShell()) {
				fLastControl = null;
			}
			// Attach the progress monitor part to the cancel button
			fProgressMonitorPart.attachToCancelComponent(null);
			fProgressMonitorPart.getParent().setVisible(true);
			fActiveRunningOperations++;

		//do work here collecting enabled states, otherwise to get these states we would need to
		//perform the validation of the dialog again, which is expensive and would cause flashing of widgets.
			Control[] children = ((Composite)fButtonComp.getChildren()[0]).getChildren();
			boolean[] prev = new boolean[children.length+2];
			prev[0] = fTabViewer.getApplyButton().isEnabled();
			prev[1] = fTabViewer.getRevertButton().isEnabled();
			for(int i = 0; i < children.length; i++) {
				prev[i+2] = children[i].isEnabled();
			}
			try {
				updateRunnnableControls(false, prev);
				ModalContext.run(runnable, fork, fProgressMonitorPart, getShell().getDisplay());
			}
			finally {
				fActiveRunningOperations--;
				updateRunnnableControls(true, prev);
				if (getShell() != null) {
					fProgressMonitorPart.getParent().setVisible(false);
					fProgressMonitorPart.removeFromCancelComponent(null);
					if (fLastControl != null && !fLastControl.isDisposed()) {
						fLastControl.setFocus();
					}
				}
			}
		}
		else {
			PlatformUI.getWorkbench().getProgressService().run(fork, cancelable, runnable);
		}
	}

	/**
	 * Updates the enablement of the runnable controls to appear disabled as a job is running
	 * @param enabled the desired enable status of the dialog area, revert//apply buttons, and
	 * @param prev the previous settings for the apply and revert buttons to be reset to, only takes effect if enable is set to true
	 * any children of the button bar
	 * @since 3.3.0
	 */
	private void updateRunnnableControls(boolean enabled, boolean[] prev) {
		fTabViewer.getApplyButton().setEnabled(enabled ? prev[0] : enabled);
		fTabViewer.getRevertButton().setEnabled(enabled ? prev[1] : enabled);
		//the arrangement never differs: button comp has one child that holds all the buttons
		Control[] children = ((Composite)fButtonComp.getChildren()[0]).getChildren();
		for(int i = 0; i < children.length; i++) {
			children[i].setEnabled(enabled ? prev[i+2] : enabled);
		}
		getDialogArea().setEnabled(enabled);
	}

	@Override
	public void setActiveTab(ILaunchConfigurationTab tab) {
		fTabViewer.setActiveTab(tab);
	}

	@Override
	public void setActiveTab(int index) {
		fTabViewer.setActiveTab(index);
	}

	/**
	 * Sets the initial selection for the dialog when opened in
	 * <code>LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION</code> mode.
	 */
	public void setInitialSelection(IStructuredSelection selection) {
		fInitialSelection = selection;
	}

	/**
	 * Sets the status to open the dialog on.
	 *
	 * @param status the initial status for the dialog
	 */
	public void setInitialStatus(IStatus status) {
		fInitialStatus = status;
	}

	/**
	 * Sets whether the tab group should set default values in the launch configuration
	 * when the dialog is opened. If this method is not called, default values are not
	 * set.
	 *
	 * @param setDefaults whether to set default values
	 * @since 3.6
	 */
	public void setDefaultsOnOpen(boolean setDefaults) {
		fSetDefaultOnOpen = setDefaults;
	}

	/**
	 * Returns if the dialog is supposed to be setting the default values for
	 * the initial configuration when it opens
	 *
	 * @return <code>true</code> if the defaults should be set on open, <code>false</code> otherwise
	 * @since 3.6
	 */
	public boolean shouldSetDefaultsOnOpen() {
		return fSetDefaultOnOpen;
	}

	/**
	 * Sets the launch group to display.
	 *
	 * @param group launch group
	 */
	protected void setLaunchGroup(LaunchGroupExtension group) {
		fGroup = group;
	}

	/**
	 * Set the title area image based on the mode this dialog was initialized with
	 */
	protected void setModeLabelState() {
		setTitleImage(getBannerImage());
	}

	@Override
	public void setName(String name) {
		fTabViewer.setName(name);
	}

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

	/**
	 * Set the flag indicating how this dialog behaves when the <code>open()</code> method is called.
	 * Valid values are defined by the LAUNCH_CONFIGURATION_DIALOG... constants in this class.
	 */
	public void setOpenMode(int mode) {
		fOpenMode = mode;
	}

	/**
 	 * Increase the size of this dialog's <code>Shell</code> by the specified amounts.
 	 * Do not increase the size of the Shell beyond the bounds of the Display.
 	 */
	protected void setShellSize(int width, int height) {
		Rectangle bounds = getShell().getMonitor().getBounds();
		getShell().setSize(Math.min(width, bounds.width), Math.min(height, bounds.height));
	}

	/**
	 * Sets the viewer used to display the tabs for a launch configuration.
	 *
	 * @param viewer the new view to set
	 */
	protected void setTabViewer(LaunchConfigurationTabGroupViewer viewer) {
		fTabViewer = viewer;
	}

	/**
	 * Create and return a dialog that asks the user whether they want to discard
	 * unsaved changes.
	 *
	 * @return the return code based on the button selected.
	 * The value will be one of <code>YES_ID</code> or <code>NO_ID</code> from
	 * <code>IDialogConstants</code>.
	 */
	private int showDiscardChangesDialog() {
		StringBuffer buffer = new StringBuffer(MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationDialog_The_configuration___35, new Object[] { fTabViewer.getWorkingCopy().getName() }));
		buffer.append(fTabViewer.getErrorMesssage());
		buffer.append(LaunchConfigurationsMessages.LaunchConfigurationDialog_Do_you_wish_to_discard_changes_37);
		MessageDialog dialog = new MessageDialog(getShell(),
												 LaunchConfigurationsMessages.LaunchConfigurationDialog_Discard_changes__38,
												 null,
												 buffer.toString(),
												 MessageDialog.QUESTION,
				new String[] {
						LaunchConfigurationsMessages.LaunchConfigurationDialog_Discard_Button,
						LaunchConfigurationsMessages.LaunchConfigurationDialog_Dont_Discard_Button },
												 1);
		int val = IDialogConstants.NO_ID;
		if (dialog.open() == 0) {
			if (fLaunchConfigurationView != null) {
				fLaunchConfigurationView.setAutoSelect(false);
			}
			fTabViewer.handleRevertPressed();
			val = IDialogConstants.YES_ID;
			if (fLaunchConfigurationView != null) {
				fLaunchConfigurationView.setAutoSelect(true);
			}
		}
		if(val == IDialogConstants.NO_ID) {
			val = ID_DISCARD_BUTTON;
		}
		return val;
	}

	/**
	 * Create and return a dialog that asks the user whether they want to save
	 * unsaved changes.
	 *
	 * @return the return code based on the button selected.
	 * The value will be one of <code>YES_ID</code>, <code>NO_ID</code>, or <code>CANCEL_ID</code>, from
	 * <code>IDialogConstants</code>.
	 */
	private int showSaveChangesDialog() {
		String message = MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationDialog_The_configuration___29, new Object[] { fTabViewer.getWorkingCopy().getName() });
		MessageDialog dialog = new MessageDialog(getShell(),
												 LaunchConfigurationsMessages.LaunchConfigurationFilteredTree_save_changes,
												 null,
												 message,
												 MessageDialog.QUESTION,
				new String[] {
						LaunchConfigurationsMessages.LaunchConfigurationDialog_Save_Button,
						LaunchConfigurationsMessages.LaunchConfigurationDialog_Dont_Save_Button,
						LaunchConfigurationsMessages.LaunchConfigurationsDialog_c_ancel },
												 0);
		int ret = dialog.open();
		int val = IDialogConstants.CANCEL_ID;
		if (ret == 0 || ret == 1) {
			if (ret == 0) {
				val = IDialogConstants.YES_ID;
			}
			else {
				val = IDialogConstants.NO_ID;
			}
		}
		return val;
	}

	/**
	 * Show the user a dialog appropriate to whether the unsaved changes in the current config
	 * can be saved or not.  Return <code>true</code> if the user indicated that they wish to replace
	 * the current config, either by saving changes or by discarding the, return <code>false</code>
	 * otherwise.
	 *
	 * @return returns the <code>showSaveChangesDialog</code> return value
	 */
	private int showUnsavedChangesDialog() {
		if (fTabViewer.canSave()) {
			return showSaveChangesDialog();
		}
		return showDiscardChangesDialog();
	}

	@Override
	public void updateButtons() {
		if (!fSettingInput) {
			// New, Delete, & Duplicate toolbar actions
	 		getNewAction().setEnabled(getNewAction().isEnabled());
			getExportAction().setEnabled(getExportAction().isEnabled());
			getDeleteAction().setEnabled(getDeleteAction().isEnabled());
			getDuplicateAction().setEnabled(getDuplicateAction().isEnabled());
			getLinkPrototypeAction().setEnabled(getLinkPrototypeAction().isEnabled());
			getUnlinkPrototypeAction().setEnabled(getUnlinkPrototypeAction().isEnabled());
			getResetWithPrototypeValuesAction().setEnabled(getResetWithPrototypeValuesAction().isEnabled());
			fTabViewer.refresh();
			getButton(ID_LAUNCH_BUTTON).setEnabled(fTabViewer.canLaunch() & fTabViewer.canLaunchWithModes() & !fTabViewer.hasDuplicateDelegates());
		} else {
			fTabViewer.refresh();
		}
	}

	@Override
	public void updateMessage() {
		if (!fSettingInput) {
			setErrorMessage(fTabViewer.getErrorMesssage());
			if (fTabViewer.getWarningMessage() != null) {
				setMessage(fTabViewer.getWarningMessage(), IMessageProvider.WARNING);
			} else {
				setMessage(fTabViewer.getMessage());
			}
		}
	}

	/**
	 * Returns if there is a selection in the tree viewer or not
	 * @return true if something in the tree is selected, false otherwise
	 * @since 3.2
	 */
	public boolean isTreeSelectionEmpty() {
		return fLaunchConfigurationView.getTreeViewer().getSelection().isEmpty();
	}

	@Override
	public void propertyChange(final PropertyChangeEvent event) {
		WorkbenchJob job = new WorkbenchJob(IInternalDebugCoreConstants.EMPTY_STRING) {
			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {
				TreeViewer viewer = fLaunchConfigurationView.getTreeViewer();
				boolean newvalue = Boolean.valueOf(event.getNewValue().toString()).booleanValue();
				if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_CLOSED)) {
					updateFilter(newvalue, fClosedProjectFilter);
				}
				else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_DELETED)) {
					updateFilter(newvalue, fDeletedProjectFilter);
				}
				else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES)) {
					updateFilter(newvalue, fLCTFilter);
				}
				else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_WORKING_SETS)) {
					updateFilter(newvalue, fWorkingSetsFilter);
				}
				else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_TYPE_LIST)) {
					if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES)) {
						viewer.refresh();
						fLaunchConfigurationView.updateFilterLabel();
					}
				}

				return Status.OK_STATUS;
			}
		};
		job.runInUIThread(new NullProgressMonitor());
	}

	/**
	 * Updates the state of a filter based on the state variable
	 * @param state if the filter needs to be added or removed, true indicates add, false indicates remove
	 * @param filter the filter to update
	 */
	private void updateFilter(boolean state, ViewerFilter filter) {
		TreeViewer viewer = (TreeViewer)fLaunchConfigurationView.getViewer();
		if(state) {
			viewer.addFilter(filter);
		}
		else {
			viewer.removeFilter(filter);
		}
		fLaunchConfigurationView.updateFilterLabel();
	}
}
