/*******************************************************************************
 *  Copyright (c) 2000, 2017 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *     Sebastian Davids - Bug 137923
 *     Mohamed Hussein (Mentor Graphics) - Added s/getWarningMessage (Bug 386673)
 *******************************************************************************/
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);
		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;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#close()
	 */
	@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());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#create()
	 */
	@Override
	public void create() {
		super.create();
		if (fTabViewer.getInput() == null) {
			fTabViewer.inputChanged(null);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createButtonBar(org.eclipse.swt.widgets.Composite)
	 */
	@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);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createContents(Composite parent) {
		Control contents = super.createContents(parent);
		initializeContent();
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), getHelpContextId());
		return contents;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	@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(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);
		getNewAction().setConfirmationRequestor(requestor);
		((StructuredViewer) viewer).addPostSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				handleLaunchConfigurationSelectionChanged(event);
				getNewAction().setEnabled(getNewAction().isEnabled());
				getDeleteAction().setEnabled(getDeleteAction().isEnabled());
				getDuplicateAction().setEnabled(getDuplicateAction().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);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#generateName(java.lang.String)
	 */
	@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);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#getActiveTab()
	 */
	@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();
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsStrategy()
     */
    @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 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;
	}

 	/* (non-Javadoc)
 	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#getMode()
 	 */
 	@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);
	}

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

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.IPageChangeProvider#getSelectedPage()
	 */
	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;
 	}

	/* (non-Javadoc)
 	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#getTabs()
 	 */
 	@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 = (IStructuredSelection) event.getSelection();
 		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();
	 					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);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#initializeBounds()
	 */
	@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();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.TitleAreaDialog#getInitialSize()
	 */
	@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();
	}

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

	/* (non-Javadoc)
	 * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean, org.eclipse.jface.operation.IRunnableWithProgress)
	 */
	@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.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);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#setActiveTab(org.eclipse.debug.ui.ILaunchConfigurationTab)
	 */
	@Override
	public void setActiveTab(ILaunchConfigurationTab tab) {
		fTabViewer.setActiveTab(tab);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#setActiveTab(int)
	 */
	@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());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#setName(java.lang.String)
	 */
	@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();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#updateButtons()
	 */
	@Override
	public void updateButtons() {
		if (!fSettingInput) {
			// New, Delete, & Duplicate toolbar actions
	 		getNewAction().setEnabled(getNewAction().isEnabled());
			getDeleteAction().setEnabled(getDeleteAction().isEnabled());
			getDuplicateAction().setEnabled(getDuplicateAction().isEnabled());
			fTabViewer.refresh();
			getButton(ID_LAUNCH_BUTTON).setEnabled(fTabViewer.canLaunch() & fTabViewer.canLaunchWithModes() & !fTabViewer.hasDuplicateDelegates());
		} else {
			fTabViewer.refresh();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchConfigurationDialog#updateMessage()
	 */
	@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();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	@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();
	}
}
