/*******************************************************************************
 *  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);
	}

	/*
	 * @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();
	}
}
