package org.eclipse.debug.internal.ui.launchConfigurations;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationListener;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.PixelConverter;
import org.eclipse.debug.internal.ui.SWTUtil;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
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.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.ControlEnableState;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Cursor;
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.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.ui.model.WorkbenchViewerSorter;

/**
 * The dialog used to edit and launch launch configurations.
 */
public class LaunchConfigurationDialog extends TitleAreaDialog 
										implements ISelectionChangedListener, 
													ILaunchConfigurationListener, 
													ILaunchConfigurationDialog, 
													IDoubleClickListener {

	/**
	 * The tree of launch configurations
	 */
	private TreeViewer fConfigTree;
	
	/**
	 * The workbench context present when this dialog is opened.
	 */
	private Object fContext;
	
	/**
	 * The IResource corresponding to <code>fContext</code>.
	 */
	private IResource fResourceContext;
	
	/**
	 * The mode (run or debug) for this dialog.
	 */
	private String fMode;
	
	/**
	 * The Composite used to insert an adjustable 'sash' between the tree and the tabs.
	 */
	private SashForm fSashForm;
	
	/**
	 * Default weights for the SashForm that specify how wide the selection and
	 * edit areas aree relative to each other.
	 */
	private static final int[] DEFAULT_SASH_WEIGHTS = new int[] {11, 30};
	
	/**
	 * The launch configuration selection area.
	 */
	private Composite fSelectionArea;	
	
	/**
	 * The launch configuration edit area.
	 */
	private Composite fEditArea;
	
	/**
	 * The 'New configuration' action.
	 */
	private ButtonAction fButtonActionNew;
	
	/**
	 * The 'Duplicate configuration' action.
	 */
	private ButtonAction fButtonActionDuplicate;
	
	/**
	 * The 'Delete configuration' action.
	 */
	private ButtonAction fButtonActionDelete;
	
	/**
	 * The 'apply' button
	 */
	private Button fApplyButton;	
	
	/**
	 * The 'revert' button
	 */
	private Button fRevertButton;
	
	/**
	 * The 'cancel' button that appears when the in-dialog progress monitor is shown.
	 */
	private Button fProgressMonitorCancelButton;
	
	/**
	 * Flag indicating if the progress monitor part's Cancel button has been pressed.
	 */
	private boolean fCancelButtonPressed;
	
	/**
	 * The text widget displaying the name of the
	 * launch configuration under edit
	 */
	private Text fNameText;
	
	private String fLastSavedName = null;
	
	/**
	 * Container for the edit area <code>TabFolder</code>
	 */
	private Composite fTabComposite;
	
	/**
	 * The tab folder that contains tabs for the selected configuration
	 */
	private TabFolder fTabFolder;
	
	/**
	 * Flag that indicates when the tabs are being disposed.
	 */
	private boolean fDisposingTabs = false;
	
	/**
	 * The current (working copy) launch configuration
	 * being displayed/edited or <code>null</code> if
	 * none
	 */
	private ILaunchConfigurationWorkingCopy fWorkingCopy;
	
	/**
	 * The actual (non-working copy) launch configuration that underlies the current working copy
	 */
	private ILaunchConfiguration fUnderlyingConfig;
	
	/**
	 * Clients of this dialog may set an 'initial configuration type', which means that when
	 * the dialog is opened, a configuration of that type will be created, initialized, and
	 * saved.  Note that the initial config type is ignored if single-click launching is enabled.
	 */
	private ILaunchConfigurationType fInitialConfigType;
	
	/**
	 * 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 current tab group being displayed
	 */
	private ILaunchConfigurationTabGroup fTabGroup;
	
	/**
	 * The type of config tabs are currently displayed
	 * for
	 */
	private ILaunchConfigurationType fTabType;
	
	/** 
	 * The index of the currently selected tab
	 */
	private int fCurrentTabIndex;
	
	private ProgressMonitorPart fProgressMonitorPart;
	private Cursor waitCursor;
	private Cursor arrowCursor;
	private MessageDialog fWindowClosingDialog;
	
	/**
	 * Whether initlialing tabs
	 */
	private boolean fInitializingTabs = false;
		
	/**
	 * Indicates if selection changes in the tree should be ignored
	 */
	private boolean fIgnoreSelectionChanges = false;
	
	/**
	 * Previously selected element in the tree
	 */
	private Object fSelectedTreeObject;
	
	/**
	 * The number of 'long-running' operations currently taking place in this dialog
	 */	
	private long fActiveRunningOperations = 0;
		
	/**
	 * 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;
	
	/**
	 * Constrant String used as key for setting and retrieving current Control with focus
	 */
	private static final String FOCUS_CONTROL = "focusControl";//$NON-NLS-1$

	/**
	 * The height in pixels of this dialog's progress indicator
	 */
	private static int PROGRESS_INDICATOR_HEIGHT = 18;

	/**
	 * 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.
	 */
	private static final float MAX_DIALOG_WIDTH_PERCENT = 0.75f;

	/**
	 * Empty array
	 */
	protected static final Object[] EMPTY_ARRAY = new Object[0];	
	
	protected static final String DEFAULT_NEW_CONFIG_NAME = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.New_configuration_1"); //$NON-NLS-1$
	
	/**
	 * Size of this dialog if there is no preference specifying a size.
	 */
	protected static final Point DEFAULT_INITIAL_DIALOG_SIZE = new Point(620, 560);

	/**
	 * Status area messages
	 */
	protected static final String LAUNCH_STATUS_OK_MESSAGE = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Ready_to_launch_2"); //$NON-NLS-1$
	protected static final String LAUNCH_STATUS_STARTING_FROM_SCRATCH_MESSAGE 
										= LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Select_a_configuration_to_launch_or_a_config_type_to_create_a_new_configuration_3"); //$NON-NLS-1$

	private String fCantSaveErrorMessage;

	/**
	 * Constant specifying that the launch configuration dialog should not actually open,
	 * but instead should attempt to re-launch the last configuration that was sucessfully
	 * launched in the workspace.  If there is no last launched configuration, just open the dialog.
	 */
	public static final int LAUNCH_CONFIGURATION_DIALOG_LAUNCH_LAST = 0;
	
	/**
	 * Constant specifying that this dialog should be opened with a new configuration of a type
	 * specified via <code>setInitialConfigType()</code> selected.
	 */
	public static final int LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_NEW_CONFIG_OF_TYPE = 1;
	
	/**
	 * 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;
	
	/**
	 * 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_LAUNCH_LAST;
	
	/**
	 * Constructs a new launch configuration dialog on the given
	 * parent shell.
	 * 
	 * @param shell the parent shell
	 * @param selection the selection used to initialize this dialog, typically the 
	 *  current workbench selection
	 * @param mode one of <code>ILaunchManager.RUN_MODE</code> or 
	 *  <code>ILaunchManager.DEBUG_MODE</code>
	 */
	public LaunchConfigurationDialog(Shell shell, IStructuredSelection selection, String mode) {
		super(shell);
		setShellStyle(getShellStyle() | SWT.RESIZE);
		setContext(resolveContext(selection));
		setMode(mode);
	}
	
	/**
	 * 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;
	}
	
	protected int getOpenMode() {
		return fOpenMode;
	}
	
	/**
	 * Returns the Object to be used as context for this dialog, derived from the specified selection.
	 * If the specified selection has as its first element an IFile whose extension matches
	 * <code>ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION</code>, then return
	 * the launch configuration declared in the IFile.  Otherwise, return the first element 
	 * in the specified selection.
	 */
	protected Object resolveContext(IStructuredSelection selection) {
		
		// Empty selection means no context
		if ((selection == null) || (selection.isEmpty())) {
			return null;
		} 

		// If first element is a launch config file, create a launch configuration from it
		// and make this the context, otherwise just return the first element
		Object firstSelected = selection.getFirstElement();
		if (firstSelected instanceof IFile) {
			IFile file = (IFile) firstSelected;
			if (ILaunchConfiguration.LAUNCH_CONFIGURATION_FILE_EXTENSION.equals(file.getFileExtension())) {
				return getLaunchManager().getLaunchConfiguration(file);
			}
		}
		return firstSelected;
	}
	
	/**
	 * 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(Composite)
	 */
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, ID_LAUNCH_BUTTON, getLaunchButtonText(), true);
		createButton(parent, ID_CLOSE_BUTTON, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Close_1"), false);  //$NON-NLS-1$
	}
	
	/**
	 * Handle the 'save and launch' & 'launch' buttons here, all others are handled
	 * in <code>Dialog</code>
	 * 
	 * @see Dialog#buttonPressed(int)
	 */
	protected void buttonPressed(int buttonId) {
		if (buttonId == ID_LAUNCH_BUTTON) {
			handleLaunchPressed();
		} else if (buttonId == ID_CLOSE_BUTTON) {
			handleClosePressed();
		} else {
			super.buttonPressed(buttonId);
		}
	}

	/**
	 * Returns the appropriate text for the launch button - run or debug.
	 */
	protected String getLaunchButtonText() {
		if (getMode() == ILaunchManager.DEBUG_MODE) {
			return LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Deb&ug_4"); //$NON-NLS-1$
		} else {
			return LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.R&un_5"); //$NON-NLS-1$
		}
	}

	/**
	 * @see Dialog#createContents(Composite)
	 */
	protected Control createContents(Composite parent) {
		Control contents = super.createContents(parent);
		initializeBounds();
		initializeSashForm();
		createContextMenu(getTreeViewer().getControl());
		getLaunchManager().addLaunchConfigurationListener(this);
		ensureSelectionAreaWidth();
		doInitialTreeSelection();
		return contents;
	}

	/**
	 * Initialize the relative weights (widths) of the 2 sides of the sash.
	 */
	protected void initializeSashForm() {
		int[] sashWeights = DEFAULT_SASH_WEIGHTS;
		String sashWeightString = getPreferenceStore().getString(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SASH_WEIGHTS);
		if (sashWeightString.length() > 0) {
			Point sashWeightPoint = parseCoordinates(sashWeightString);
			if (sashWeightPoint != null) {
				sashWeights[0] = sashWeightPoint.x;
				sashWeights[1] = sashWeightPoint.y;
			}
		}
		getSashForm().setWeights(sashWeights);
	}

	/**
	 * Check if the selection area is currently wide enough so that both the 'New' &
	 * 'Delete' buttons are shown without truncation.  If so, do nothing.  Otherwise,
	 * increase the width of this dialog's Shell just enough so that both buttons 
	 * are shown cleanly.
	 */
	protected void ensureSelectionAreaWidth() {
		Button newButton = getButtonActionNew().getButton();
		Button deleteButton = getButtonActionDelete().getButton();		
		int requiredWidth = newButton.getBounds().width + deleteButton.getBounds().width;
		int marginWidth = ((GridLayout)getSelectionArea().getLayout()).marginWidth;
		int horizontalSpacing = ((GridLayout)getSelectionArea().getLayout()).horizontalSpacing;
		requiredWidth += (2 * marginWidth) + horizontalSpacing;
		int currentWidth = getSelectionArea().getBounds().width;

		if (requiredWidth > currentWidth) {
			int[] newSashWeights = new int[2];
			newSashWeights[0] = requiredWidth;
			newSashWeights[1] = getEditArea().getBounds().width;
			Shell shell= getShell();
			Point shellSize= shell.getSize();
			setShellSize(shellSize.x + (requiredWidth - currentWidth), shellSize.y);
			getSashForm().setWeights(newSashWeights);			
		}
	}
	
	/**
	 * Creates a pop-up menu on the specified control.
	 */
	protected void createContextMenu(Control menuControl) {
		MenuManager menuMgr= new MenuManager("#PopUp"); //$NON-NLS-1$
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager mgr) {
				fillContextMenu(mgr);
			}
		});
		Menu menu= menuMgr.createContextMenu(menuControl);
		menuControl.setMenu(menu);
	}
	
	/**
	 * Fill the specified context menu with the basic launch configuration
	 * management actions - New, Duplicate & Delete.
	 */
	protected void fillContextMenu(IMenuManager menu) {	
		if (getButtonActionNew().isEnabled()) {
			menu.add(getButtonActionNew());
		}
		if (getButtonActionDuplicate().isEnabled()) {
			menu.add(getButtonActionDuplicate());
		}
		if (getButtonActionDelete().isEnabled()) {
			menu.add(getButtonActionDelete());
		}
	}	
	
	/**
	 * Set the initial selection in the tree.
	 */
	protected void doInitialTreeSelection() {
		getTreeViewer().setSelection(getInitialSelection());
	}
	
	/**
	 * Write out this dialog's Shell size, location & sash weights to the preference store.
	 */
	protected void persistShellGeometry() {
		Point shellLocation = getShell().getLocation();
		Point shellSize = getShell().getSize();
		int[] sashWeights = getSashForm().getWeights();
		String locationString = serializeCoords(shellLocation);
		String sizeString = serializeCoords(shellSize);
		String sashWeightString = serializeCoords(new Point(sashWeights[0], sashWeights[1]));
		getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_LOCATION, locationString);
		getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SIZE, sizeString);
		getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SASH_WEIGHTS, sashWeightString);
	}
	
	/**
	 * @see Window#close()
	 */
	public boolean close() {
		getLaunchManager().removeLaunchConfigurationListener(this);
		persistShellGeometry();
		return super.close();
	}
	
	/**
	 * Determine the first configuration for this dialog.  If single-click launching is 
	 * enabled, launch the configuration WITHOUT realizing the dialog.  If single-click 
	 * launching was successful, this method returns 
	 * <code>ILaunchConfigurationDialog.SINGLE_CLICK_LAUNCHED</code>.  Otherwise, open the
	 * dialog in the specified mode.
	 * 
	 * @see Window#open()
	 */
	public int open() {		
		int mode = getOpenMode();	
		if (mode == LAUNCH_CONFIGURATION_DIALOG_LAUNCH_LAST) {
			return doLastLaunchedConfig(true);
		} else if (mode == LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED) {
			return doLastLaunchedConfig(false);
		} else if (mode == LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_NEW_CONFIG_OF_TYPE) {
			return openDialogOnNewConfigOfSpecifiedType();
		} else if (mode == LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION) {
			return openDialogOnSelection();
		}		
		return super.open();
	}
	
	/**
	 * Retrieve the last launched configuration in the workspace.  If <code>launch</code>
	 * is <code>true</code>, launch this configuration without showing the dialog, otherwise 
	 * just set the initial selection in the dialog to the last launched configuration.
	 */
	protected int doLastLaunchedConfig(boolean launch) {
		ILaunchConfiguration lastLaunchedConfig = getLastLaunchedWorkbenchConfiguration();
		if (launch) {
			try {
				if (lastLaunchedConfig != null) {
					if (lastLaunchedConfig.supportsMode(getMode())) {
						fUnderlyingConfig = lastLaunchedConfig;
						doLaunch(lastLaunchedConfig);
					} else {
						// If we're trying to launch, but the last launched config doesn't 
						// support the current mode of the dialog, show an error dialog
						String configName = lastLaunchedConfig.getName();
						String title = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cannot_relaunch_1"); //$NON-NLS-1$
						String message = MessageFormat.format(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cannot_relaunch_[{1}]_because_it_does_not_support_{2}_mode_2"), new String[] {configName, getMode()}); //$NON-NLS-1$
						MessageDialog.openError(getShell(), title, message);										
					}
					return ILaunchConfigurationDialog.LAUNCHED_BEFORE_OPENING;
				}
			} catch(CoreException e) {
				DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configuration_Error_6"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_processing_launch_configuration._See_log_for_more_information_7"), e); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
		if (lastLaunchedConfig != null) {
			setInitialSelection(new StructuredSelection(lastLaunchedConfig));
		}			
		return super.open();
	}
	
	/**
	 * Realize this dialog so that a new configuration of the type that was specified via
	 * <code>setInitialConfigType()</code> is selected.
	 */
	protected int openDialogOnNewConfigOfSpecifiedType() {
		ILaunchConfigurationType configType = getInitialConfigType();
		ILaunchConfiguration config = null;
		if (configType != null) {
			config = createConfigOfType(configType);			
		}		
		if (config != null) {
			setInitialSelection(new StructuredSelection(config));
		}
		return super.open();
	}
	
	/**
	 * Open this dialog with the selection set to the value specified by 
	 * <code>setInitialSelection()</code>.
	 */
	protected int openDialogOnSelection() {
		// Nothing special is required, the dialog will open and whatever was specified
		// via setInitialSelection() will be selected in the tree
		return super.open();
	}
	
	/**
	 * Return the last launched configuration in the workspace.
	 */
	protected ILaunchConfiguration getLastLaunchedWorkbenchConfiguration() {
		LaunchConfigurationHistoryElement historyElement = DebugUIPlugin.getLaunchConfigurationManager().getLastLaunch();
		if (historyElement != null) {
			return historyElement.getLaunchConfiguration();
		}
		return null;			
	}
	
	/**
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
	 */
	protected Control createDialogArea(Composite parent) {
		GridData gd;
		Composite dialogComp = (Composite)super.createDialogArea(parent);
		Composite topComp = new Composite(dialogComp, SWT.NONE);
		gd = new GridData(GridData.FILL_BOTH);
		topComp.setLayoutData(gd);
		GridLayout topLayout = new GridLayout();
		topLayout.numColumns = 2;
		topLayout.marginHeight = 5;
		topLayout.marginWidth = 0;
		topComp.setLayout(topLayout);

		// Set the things that TitleAreaDialog takes care of
		setTitle(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Create,_manage,_and_run_launch_configurations_8")); //$NON-NLS-1$
		setMessage(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Ready_to_launch_2")); //$NON-NLS-1$
		setModeLabelState();

		// Create the SashForm that contains the selection area on the left,
		// and the edit area on the right
		setSashForm(new SashForm(topComp, SWT.NONE));
		getSashForm().setOrientation(SWT.HORIZONTAL);
		gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 2;
		getSashForm().setLayoutData(gd);
		
		// Build the launch configuration selection area and put it into the composite.
		Composite launchConfigSelectionArea = createLaunchConfigurationSelectionArea(getSashForm());
		gd = new GridData(GridData.FILL_VERTICAL);
		launchConfigSelectionArea.setLayoutData(gd);
	
		// Build the launch configuration edit area and put it into the composite.
		Composite editAreaComp = createLaunchConfigurationEditArea(getSashForm());
		gd = new GridData(GridData.FILL_BOTH);
		editAreaComp.setLayoutData(gd);
			
		// Build the separator line that demarcates the button bar
		Label separator = new Label(topComp, SWT.HORIZONTAL | SWT.SEPARATOR);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		gd.horizontalSpan = 2;
		separator.setLayoutData(gd);
		
		dialogComp.layout(true);
		
		return dialogComp;
	}
	
	/**
	 * Create and return a launch configuration of the specified type.
	 * This method is intended to be called before the UI has been realized, such as in
	 * the case of single-click launching or creating a config for an initial configuration
	 * type.
	 */
	protected ILaunchConfiguration createConfigOfType(ILaunchConfigurationType configType) {		
		ILaunchConfigurationWorkingCopy workingCopy = null;
		try {
			workingCopy = configType.newInstance(null, getLaunchManager().generateUniqueLaunchConfigurationNameFrom(DEFAULT_NEW_CONFIG_NAME));
		} catch (CoreException ce) {
			DebugUIPlugin.log(ce);
			return null;
		}

		ILaunchConfiguration config = null;
		try {
	 		ILaunchConfigurationTabGroup group= createGroup(configType);
	 		group.setDefaults(workingCopy);
	 		group.dispose();

 			// Assign a name to the config if it doesn't already have one
	 		if (workingCopy.getName().trim().length() == 0) {
	 			IResource res = getResourceContext();
	 			String name = "";       //$NON-NLS-1$
	 			if (res != null) {
	 				name = res.getName();
	 			}
	 			name = generateName(name);
	 			workingCopy.rename(name);
	 		}
	 		
	 		config = workingCopy.doSave();
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
			return null;
		}
		
		return config;
	}
	
	/**
	 * Returns tab group for the given type of launch configuration.
	 * Tabs are initialized to be contained in this dialog.
	 * 
	 * @exception CoreException if unable to instantiate a tab group
	 */
	protected ILaunchConfigurationTabGroup createGroup(final ILaunchConfigurationType configType) throws CoreException {
		// Use a final Object array to store the tab group and any exception that
		// results from the Runnable
		final Object[] finalArray = new Object[2]; 		
 		Runnable runnable = new Runnable() {
 			public void run() {
		 		ILaunchConfigurationTabGroup tabGroup = null;
				try {
					tabGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(configType);
					finalArray[0] = tabGroup;
				} catch (CoreException ce) {
					finalArray[1] = ce;
					return;
				}
		 		tabGroup.createTabs(LaunchConfigurationDialog.this, getMode());
		 		ILaunchConfigurationTab[] tabs = tabGroup.getTabs();
		 		for (int i = 0; i < tabs.length; i++) {
		 			tabs[i].setLaunchConfigurationDialog(LaunchConfigurationDialog.this);
		 		}
 			}
 		};
 		
 		// Creating the tabs can result in plugin loading, so we show the busy cursor
 		BusyIndicator.showWhile(getDisplay(), runnable);
 		
 		// Re-throw any CoreException if there was one
 		if (finalArray[1] != null) {
 			throw (CoreException)finalArray[1];
 		}
 		
 		// Otherwise return the tab group
 		return (ILaunchConfigurationTabGroup)finalArray[0];
	}
	
	/**
	 * Returns the selected IResource context from the workbench,
	 * or <code>null</code> if there was no context in the workbench.
	 */
	protected IResource getResourceContext() {
		if (fResourceContext == null) {
			Object workbenchSelection = getContext();
			if (workbenchSelection instanceof IResource) {
				fResourceContext = (IResource)workbenchSelection;
			} else if (workbenchSelection instanceof IAdaptable) {
				fResourceContext = (IResource) ((IAdaptable)workbenchSelection).getAdapter(IResource.class);
			}
		}
		return fResourceContext;		
	}
	
	/**
	 * Set the title area image based on the mode this dialog was initialized with
	 */
	protected void setModeLabelState() {
		Image image;
		if (getMode().equals(ILaunchManager.DEBUG_MODE)) {
			image = DebugUITools.getImage(IDebugUIConstants.IMG_WIZBAN_DEBUG);
		} else {
			image = DebugUITools.getImage(IDebugUIConstants.IMG_WIZBAN_RUN);
		}
		setTitleImage(image);
	}
	
	/**
	 * Convenience method to set the selection on the configuration tree.
	 */
	protected void setTreeViewerSelection(ISelection selection) {
		getTreeViewer().setSelection(selection);
	}
	
	private void setLastSavedName(String lastSavedName) {
		this.fLastSavedName = lastSavedName;
	}

	private String getLastSavedName() {
		return fLastSavedName;
	}
	
	/**
	 * Update buttons and message.
	 */
	protected void refreshStatus() {
		updateButtons();
		updateMessage();
	}
	
	/**
	 * Verify the attributes common to all launch configuration.
	 * Indicate failure by throwing a <code>CoreException</code>.
	 */
	protected void verifyStandardAttributes() throws CoreException {
		verifyName();
	}
	
	/**
	 * Verify that the launch configuration name is valid.
	 */
	protected void verifyName() throws CoreException {
		String currentName = getNameTextWidget().getText().trim();

		// If there is no name, complain
		if (currentName.length() < 1) {
			throw new CoreException(new Status(IStatus.ERROR,
												 DebugUIPlugin.getUniqueIdentifier(),
												 0,
												 LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Name_required_for_launch_configuration_11"), //$NON-NLS-1$
												 null));			
		}

		// If the name hasn't changed from the last saved name, do nothing
		if (currentName.equals(getLastSavedName())) {
			return;
		}	
		
		// See if name contains any 'illegal' characters
		IStatus status = ResourcesPlugin.getWorkspace().validateName(currentName, IResource.FILE);
		if (status.getCode() != IStatus.OK) {
			throw new CoreException(new Status(IStatus.ERROR,
												 DebugUIPlugin.getDefault().getDescriptor().getUniqueIdentifier(),
												 0,
												 status.getMessage(),
												 null));									
		}			
		
		// Otherwise, if there's already a config with the same name, complain
		if (getLaunchManager().isExistingLaunchConfigurationName(currentName)) {
			throw new CoreException(new Status(IStatus.ERROR,
												 DebugUIPlugin.getDefault().getDescriptor().getUniqueIdentifier(),
												 0,
												 LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_configuration_already_exists_with_this_name_12"), //$NON-NLS-1$
												 null));						
		}						
	}
	
	/**
	 * If the name is valid, rename the current launch configuration.  Otherwise, show an
	 * appropriate error message.
	 */
	protected void updateConfigFromName() {
		if (getLaunchConfiguration() != null) {
			try {
				verifyName();
			} catch (CoreException ce) {
				refreshStatus();
				return;				
			}
						
			getLaunchConfiguration().rename(getNameTextWidget().getText().trim());
			refreshStatus();
		}
	}
	
	protected Display getDisplay() {
		Shell shell = getShell();
		if (shell != null) {
			return shell.getDisplay();
		} else {
			return Display.getDefault();
		}
	}
		
	/**
	 * 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 Composite createLaunchConfigurationSelectionArea(Composite parent) {
		Composite comp = new Composite(parent, SWT.NONE);
		setSelectionArea(comp);
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;
		layout.marginHeight = 0;
		layout.marginWidth = 5;
		comp.setLayout(layout);
		
		Label treeLabel = new Label(comp, SWT.NONE);
		treeLabel.setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Con&figurations__1")); //$NON-NLS-1$
		GridData gd = new GridData();
		gd.horizontalSpan = 3;
		treeLabel.setLayoutData(gd);
		
		TreeViewer tree = new TreeViewer(comp);
		gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 3;
		// Set width hint to 0 to force tree to only be as wide as the combined
		// width of the 'New' & 'Delete' buttons.  Otherwise tree wants to be much wider.
		gd.widthHint = 0;
		tree.getControl().setLayoutData(gd);
		tree.setContentProvider(new LaunchConfigurationContentProvider());
		tree.setLabelProvider(DebugUITools.newDebugModelPresentation());
		tree.setSorter(new WorkbenchViewerSorter());
		setTreeViewer(tree);
		tree.addSelectionChangedListener(this);
		tree.setInput(ResourcesPlugin.getWorkspace().getRoot());
		tree.expandAll();
		tree.addDoubleClickListener(this);
		tree.getControl().addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				handleKeyPressed(e);
			}
		});
		
		Button newButton = SWTUtil.createPushButton(comp, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Ne&w_13"), null); //$NON-NLS-1$
		setButtonActionNew(new ButtonActionNew(newButton.getText(), newButton));
		
		Button deleteButton = SWTUtil.createPushButton(comp, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Dele&te_14"), null); //$NON-NLS-1$
		setButtonActionDelete(new ButtonActionDelete(deleteButton.getText(), deleteButton));
		
		setButtonActionDuplicate(new ButtonActionDuplicate(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Duplicate_1"), null)); //$NON-NLS-1$
		
		return comp;
	}	
	
	/**
	 * 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) {
		Composite outerComp = new Composite(parent, SWT.NONE);
		GridLayout outerCompLayout = new GridLayout();
		outerCompLayout.numColumns = 1;
		outerCompLayout.marginHeight = 0;
		outerCompLayout.marginWidth = 0;
		outerComp.setLayout(outerCompLayout);
		
		Composite comp = new Composite(outerComp, SWT.NONE);
		setEditArea(comp);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight = 0;
		layout.marginWidth = 5;
		comp.setLayout(layout);		
		GridData gd = new GridData(GridData.FILL_BOTH);
		comp.setLayoutData(gd);
		
		Label nameLabel = new Label(comp, SWT.HORIZONTAL | SWT.LEFT);
		nameLabel.setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.&Name__16")); //$NON-NLS-1$
		gd = new GridData(GridData.BEGINNING);
		nameLabel.setLayoutData(gd);
		
		Text nameText = new Text(comp, SWT.SINGLE | SWT.BORDER);
		gd = new GridData(GridData.FILL_HORIZONTAL);
		nameText.setLayoutData(gd);
		setNameTextWidget(nameText);
		
		getNameTextWidget().addModifyListener(
			new ModifyListener() {
				public void modifyText(ModifyEvent e) {
					updateConfigFromName();
				}
			}
		);		
		
		Label spacer = new Label(comp, SWT.NONE);
		gd = new GridData();
		gd.horizontalSpan = 2;
		spacer.setLayoutData(gd);
		
		fTabComposite = new Composite(comp, SWT.NONE);
		GridLayout outerTabCompositeLayout = new GridLayout();
		outerTabCompositeLayout.marginHeight = 0;
		outerTabCompositeLayout.marginWidth = 0;
		fTabComposite.setLayout(outerTabCompositeLayout);
		gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 2;
		fTabComposite.setLayoutData(gd);		
		
		TabFolder tabFolder = new TabFolder(fTabComposite, SWT.NONE);
		setTabFolder(tabFolder);
		gd = new GridData(GridData.FILL_BOTH);
		tabFolder.setLayoutData(gd);
		getTabFolder().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				handleTabSelected();
			}
		});
		
		Composite buttonComp = new Composite(comp, SWT.NONE);
		GridLayout buttonCompLayout = new GridLayout();
		buttonCompLayout.numColumns = 2;
		buttonComp.setLayout(buttonCompLayout);
		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		gd.horizontalSpan = 2;
		buttonComp.setLayoutData(gd);
		
		setApplyButton(new Button(buttonComp, SWT.PUSH));
		getApplyButton().setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.&Apply_17")); //$NON-NLS-1$
		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		getApplyButton().setLayoutData(gd);
		SWTUtil.setButtonDimensionHint(getApplyButton());
		getApplyButton().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				handleApplyPressed();
			}
		});
		
		setRevertButton(new Button(buttonComp, SWT.PUSH));
		getRevertButton().setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Revert_2"));   //$NON-NLS-1$
		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
		getRevertButton().setLayoutData(gd);
		SWTUtil.setButtonDimensionHint(getRevertButton());
		getRevertButton().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				handleRevertPressed();
			}
		});
		
		return outerComp;
	}	
	
	/**
	 * @see Dialog#createButtonBar(Composite)
	 */
	protected Control createButtonBar(Composite parent) {
		Composite composite= new Composite(parent, SWT.NULL);
		GridLayout layout= new GridLayout();
		layout.numColumns= 2;
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		GridLayout pmLayout = new GridLayout();
		pmLayout.numColumns = 3;
		setProgressMonitorPart(new ProgressMonitorPart(composite, pmLayout, PROGRESS_INDICATOR_HEIGHT));
		Button cancelButton = createButton(getProgressMonitorPart(), ID_CANCEL_BUTTON, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cancel_3"), true); //$NON-NLS-1$
		setProgressMonitorCancelButton(cancelButton);
		getProgressMonitorCancelButton().addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent evt) {
				setCancelButtonPressed(true);
			}
		});
		getProgressMonitorPart().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		getProgressMonitorPart().setVisible(false);

		return super.createButtonBar(composite);
	}
	
	/**
	 * Sets the title for the dialog, and establishes the help context.
	 * 
	 * @see org.eclipse.jface.window.Window#configureShell(Shell);
	 */
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configurations_18")); //$NON-NLS-1$
		WorkbenchHelp.setHelp(
			shell,
			IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG);
	}
	
	/**
	 * @see Window#getInitialLocation(Point)
	 */
	protected Point getInitialLocation(Point initialSize) {	
		String locationString = getPreferenceStore().getString(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_LOCATION);
		if (locationString.length() > 0) {
			Point locationPoint = parseCoordinates(locationString);
			if (locationPoint != null) {
				return locationPoint;
			}
		}
		return super.getInitialLocation(initialSize);
	}

	/**
	 * @see Window#getInitialSize()
	 */
	protected Point getInitialSize() {
		String sizeString = getPreferenceStore().getString(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SIZE);
		if (sizeString.length() > 0) {
			Point sizePoint = parseCoordinates(sizeString);
			if (sizePoint != null) {
				return sizePoint;
			}
		}
		return DEFAULT_INITIAL_DIALOG_SIZE;
	}
	
	/**
	 * Given a coordinate String of the form "123x456" return a Point object whose
	 * X value is 123 and Y value is 456.  Return <code>null</code> if the String
	 * is not in the specified form.
	 */
	protected Point parseCoordinates(String coordString) {
		int byIndex = coordString.indexOf('x');
		if (byIndex < 0) {
			return null;
		}
		
		try {
			int x = Integer.parseInt(coordString.substring(0, byIndex));
			int y = Integer.parseInt(coordString.substring(byIndex + 1));			
			return new Point(x, y);
		} catch (NumberFormatException nfe) {
			return null;
		}
	}
	
	/**
	 * Given a Point object, return a String of the form "XCoordxYCoord".
	 */
	protected String serializeCoords(Point coords) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(coords.x);
		buffer.append('x');
		buffer.append(coords.y);
		return buffer.toString();
	}
	
	private void setSashForm(SashForm sashForm) {
		fSashForm = sashForm;
	}
	
	protected SashForm getSashForm() {
		return fSashForm;
	}

	/**
	 * Sets the tree viewer used to display launch configurations.
	 * 
	 * @param viewer the tree viewer used to display launch
	 *  configurations
	 */
	private void setTreeViewer(TreeViewer viewer) {
		fConfigTree = viewer;
	}
	
	/**
	 * Returns the tree viewer used to display launch configurations.
	 * 
	 * @param the tree viewer used to display launch configurations
	 */
	protected TreeViewer getTreeViewer() {
		return fConfigTree;
	}
	
	protected IStructuredSelection getTreeViewerSelection() {
		return (IStructuredSelection)getTreeViewer().getSelection();
	}
	
	protected Object getTreeViewerFirstSelectedElement() {
		IStructuredSelection selection = getTreeViewerSelection();
		if (selection == null) {
			return null;
		}
		return selection.getFirstElement();
	}
		
	/**
	 * Content provider for launch configuration tree.
	 */
	class LaunchConfigurationContentProvider implements ITreeContentProvider {
		
		/**
		 * Actual launch configurations have no children.  Launch configuration types have
		 * all configurations of that type as children, minus any configurations that are 
		 * marked as private.
		 * 
		 * @see ITreeContentProvider#getChildren(Object)
		 */
		public Object[] getChildren(Object parentElement) {
			if (parentElement instanceof ILaunchConfiguration) {
				return EMPTY_ARRAY;
			} else if (parentElement instanceof ILaunchConfigurationType) {
				try {
					ILaunchConfigurationType type = (ILaunchConfigurationType)parentElement;
					ILaunchConfiguration[] allConfigs = getLaunchManager().getLaunchConfigurations(type);
					ArrayList filteredConfigs = new ArrayList(allConfigs.length);
					for (int i = 0; i < allConfigs.length; i++) {
						ILaunchConfiguration config = allConfigs[i];
						if (config.getAttribute(IDebugUIConstants.ATTR_PRIVATE, false)) {
							continue;
						}
						filteredConfigs.add(config);
					}
					return filteredConfigs.toArray();
				} catch (CoreException e) {
					DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Error_19"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.An_exception_occurred_while_retrieving_launch_configurations_20"), e); //$NON-NLS-1$ //$NON-NLS-2$
				}
			} else {
				return getLaunchManager().getLaunchConfigurationTypes();
			}
			return EMPTY_ARRAY;
		}

		/**
		 * @see ITreeContentProvider#getParent(Object)
		 */
		public Object getParent(Object element) {
			if (element instanceof ILaunchConfiguration) {
				if (!((ILaunchConfiguration)element).exists()) {
					return null;
				}
				try {
					return ((ILaunchConfiguration)element).getType();
				} catch (CoreException e) {
					DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Error_19"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.An_exception_occurred_while_retrieving_launch_configurations_20"), e); //$NON-NLS-1$ //$NON-NLS-2$
				}
			} else if (element instanceof ILaunchConfigurationType) {
				return ResourcesPlugin.getWorkspace().getRoot();
			}
			return null;
		}

		/**
		 * @see ITreeContentProvider#hasChildren(Object)
		 */
		public boolean hasChildren(Object element) {
			if (element instanceof ILaunchConfiguration) {
				return false;
			} else {
				return getChildren(element).length > 0;
			}
		}

		/**
		 * Return only the launch configuration types that support the current mode AND
		 * are marked as 'public'.
		 * 
		 * @see IStructuredContentProvider#getElements(Object)
		 */
		public Object[] getElements(Object inputElement) {
			ILaunchConfigurationType[] allTypes = getLaunchManager().getLaunchConfigurationTypes();
			ArrayList list = new ArrayList(allTypes.length);
			String mode = getMode();
			for (int i = 0; i < allTypes.length; i++) {
				ILaunchConfigurationType configType = allTypes[i];
				if (configType.supportsMode(mode) && configType.isPublic()) {
					list.add(configType);
				}
			}			
			return list.toArray();
		}

		/**
		 * @see IContentProvider#dispose()
		 */
		public void dispose() {
		}

		/**
		 * @see IContentProvider#inputChanged(Viewer, Object, Object)
		 */
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}

	}
	
	/**
	 * Returns the launch manager.
	 * 
	 * @return the launch manager
	 */
	protected ILaunchManager getLaunchManager() {
		return DebugPlugin.getDefault().getLaunchManager();
	}

	/**
	 * Returns whether this dialog is currently open
	 */
	protected boolean isVisible() {
		return getTreeViewer() != null;
	}	
		
	/**
	 * 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
	 */
 	public void selectionChanged(SelectionChangedEvent event) {
 		
 		// Ignore selectionChange events that occur while saving
 		if (ignoreSelectionChanges()) {
 			return;
 		}
 		
 		// Get the new selection		
 		IStructuredSelection selection = (IStructuredSelection)event.getSelection();
 		if (selection.isEmpty()) {
 			getEditArea().setVisible(false);
 			setWorkingCopy(null);
 			setSelectedTreeObject(null);
 			updateButtons();
 			return;
 		}
 		
 		// Get details of the new selection
 		Object firstSelectedElement = selection.getFirstElement();		
 		boolean singleSelection = selection.size() == 1;
		boolean configSelected = firstSelectedElement instanceof ILaunchConfiguration;

 		// If selection is the same, don't bother
 		Object lastSelectedTreeObj = getSelectedTreeObject();
 		if (singleSelection && (lastSelectedTreeObj != null) && lastSelectedTreeObj.equals(firstSelectedElement)) {
 			getEditArea().setVisible(lastSelectedTreeObj instanceof ILaunchConfiguration);
 			return;
 		}
 		
		// Take care of any unsaved changes.  If the user aborts, reset selection
		// to whatever it was previously selected
		boolean canReplaceConfig = canDiscardCurrentConfig();
 		if (!canReplaceConfig) {
 			StructuredSelection prevSelection;
			if (lastSelectedTreeObj == null) {
				prevSelection = StructuredSelection.EMPTY;
			} else {
				prevSelection = new StructuredSelection(lastSelectedTreeObj);
			}
 			setTreeViewerSelection(prevSelection);
 			return;
 		}			
 				 		 		 
		// If a config is selected, update the edit area for it, if a config type is
		// selected, clear the edit area
 		if (singleSelection && configSelected) {
 			ILaunchConfiguration config = (ILaunchConfiguration) firstSelectedElement; 			
 			setLastSavedName(config.getName());
 			setLaunchConfiguration(config, false);
 		} else if (singleSelection && firstSelectedElement instanceof ILaunchConfigurationType) {
			if (canReplaceConfig) {
				clearLaunchConfiguration();
				getEditArea().setVisible(false);
				disposeExistingTabs();
			}
 		} else {
 			// multi-selection
 			clearLaunchConfiguration();
 			getEditArea().setVisible(false);
 		}
 		
 		updateButtons();
 		if (singleSelection) {
	 		setSelectedTreeObject(firstSelectedElement);
 		} else {
 			setSelectedTreeObject(null);
 		}
 	}
 	
 	protected void setProgressMonitorPart(ProgressMonitorPart part) {
 		fProgressMonitorPart = part;
 	}
 	
 	protected ProgressMonitorPart getProgressMonitorPart() {
 		return fProgressMonitorPart;
 	}
 	
 	protected void setProgressMonitorCancelButton(Button button) {
 		fProgressMonitorCancelButton = button;
 	}
 	
 	protected Button getProgressMonitorCancelButton() {
 		return fProgressMonitorCancelButton;
 	}
 	
 	/**
 	 * Sets the configuration to display/edit.
 	 * Updates the tab folder to contain the appropriate pages.
 	 * Sets all configuration-related state appropriately.
 	 * 
 	 * @param config the launch configuration to display/edit
 	 * @param init whether to initialize the config with default values
 	 */
 	protected void setLaunchConfiguration(ILaunchConfiguration config, boolean init) {
		try {
			
			// turn on initializing flag to ignore message updates
			setInitializingTabs(true);
			
			getEditArea().setVisible(true);
			showTabsForConfigType(config.getType());
			
			if (config.isWorkingCopy()) {
		 		setWorkingCopy((ILaunchConfigurationWorkingCopy)config);
			} else {
				setWorkingCopy(config.getWorkingCopy());
			}
			fUnderlyingConfig = getLaunchConfiguration().getOriginal();
	 		
	 		// update the name field before to avoid verify error 
	 		getNameTextWidget().setText(config.getName());	 		
	 			 		
	 		// Set the defaults for all tabs before any are initialized
	 		// so that every tab can see ALL the default values
	 		if (init) {
				getTabGroup().setDefaults(getLaunchConfiguration());
	 		}

	 		// update the tabs with the new working copy	 		
			getTabGroup().initializeFrom(getLaunchConfiguration());
	 		
	 		// update the name field after in case client changed it 
	 		getNameTextWidget().setText(config.getName());
	 				
	 		// turn off initializing flag to update message
			setInitializingTabs(false);
			
	 		refreshStatus();
	 		
		} catch (CoreException ce) {
 			DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Error_19"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_setting_launch_configuration_24"), ce); //$NON-NLS-1$ //$NON-NLS-2$
 			clearLaunchConfiguration();
 			return;					
		}
 	} 
 	
 	/**
 	 * Clears the configuration being shown/edited.   
 	 * Resets all configuration-related state.
 	 */
 	protected void clearLaunchConfiguration() {
 		setWorkingCopy(null);
 		fUnderlyingConfig = null;
 		setLastSavedName(null);
 		getNameTextWidget().setText("");  //$NON-NLS-1$
 		refreshStatus();
 	}
 	
 	/**
 	 * Populate the tabs in the configuration edit area to be appropriate to the current
 	 * launch configuration type.
 	 */
 	protected void showTabsForConfigType(ILaunchConfigurationType configType) {		
 		
 		// Don't do any work if the current tabs are for the current config type
 		if (getTabType() != null && getTabType().equals(configType)) {
 			return;
 		}
 		
 		// Avoid flicker
 		getEditArea().setVisible(false);
 		
		// Dispose the current tabs
		disposeExistingTabs();

		// Build the new tabs
 		ILaunchConfigurationTabGroup group = null;
 		try {
	 		group = createGroup(configType);
 		} catch (CoreException ce) {
 			DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Error_19"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_creating_launch_configuration_tabs_27"),ce); //$NON-NLS-1$ //$NON-NLS-2$
 			return;
 		}
 		
 		// Create the Control for each tab, and determine the maximum tab dimensions
 		PixelConverter pixelConverter = new PixelConverter(getTabFolder());
 		int runningTabWidth = 0;
 		ILaunchConfigurationTab[] tabs = group.getTabs();
 		Point contentSize = new Point(0, 0);
 		for (int i = 0; i < tabs.length; i++) {
 			TabItem tab = new TabItem(getTabFolder(), SWT.NONE);
 			String name = tabs[i].getName();
 			if (name == null) {
 				name = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.unspecified_28"); //$NON-NLS-1$
 			}
 			tab.setText(name);
 			Image image = tabs[i].getImage();
 			tab.setImage(image);
 			runningTabWidth += pixelConverter.convertWidthInCharsToPixels(name.length() + 5);
 			if (image != null) {
	 			runningTabWidth += image.getBounds().width;
 			}
 			tabs[i].createControl(tab.getParent());
 			Control control = tabs[i].getControl();
 			if (control != null) {
	 			tab.setControl(control);
	 			Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
	 			if (size.x > contentSize.x) {
	 				contentSize.x = size.x;
	 			}
	 			if (size.y > contentSize.y) {
	 				contentSize.y = size.y;
	 			}
 			}
 		}
 		
 		// Determine if more space is needed to show all tab labels across the top of the
 		// tab folder.  If so, only increase size of dialog to some percent of the available
 		// screen real estate.
		if (runningTabWidth > contentSize.x) {
			int maxAllowedWidth = (int) (getDisplay().getBounds().width * MAX_DIALOG_WIDTH_PERCENT);
			int otherWidth = getSashForm().SASH_WIDTH + getSelectionArea().getBounds().width;
			int totalWidth = runningTabWidth + otherWidth;
			if (totalWidth > maxAllowedWidth) {
				contentSize.x = maxAllowedWidth - otherWidth;
			} else {
				contentSize.x = runningTabWidth;
			} 
		}
 		
 		// Adjust the maximum tab dimensions to account for the extra space required for the tab labels
 		Rectangle tabFolderBoundingBox = getTabFolder().computeTrim(0, 0, contentSize.x, contentSize.y);
		contentSize.x = tabFolderBoundingBox.width;
		contentSize.y = tabFolderBoundingBox.height;

 		// Force recalculation of sizes	
		getTabFolder().layout(true);
		
		// Calculate difference between required space for tab folder and current size,
		// then increase size of this dialog's Shell by that amount
 		Rectangle rect = fTabComposite.getClientArea();
		Point containerSize= new Point(rect.width, rect.height);
		int hdiff= contentSize.x - containerSize.x;
		int vdiff= contentSize.y - containerSize.y;
		// Only increase size of dialog, never shrink it
		if (hdiff > 0 || vdiff > 0) {
			int[] newSashWeights = null;
			if (hdiff > 0) {			
				newSashWeights = calculateNewSashWeights(hdiff);				
			}
			hdiff= Math.max(0, hdiff);
			vdiff= Math.max(0, vdiff);
			Shell shell= getShell();
			Point shellSize= shell.getSize();
			setShellSize(shellSize.x + hdiff, shellSize.y + vdiff);
			// Adjust the sash weights so that all of the increase in width
			// is given to the tab area
			if (newSashWeights != null) {
				getSashForm().setWeights(newSashWeights);
			}
		}

 		setTabGroup(group);
 		setTabType(configType);
 		getEditArea().setVisible(true);
 	}
 	
 	/**
 	 * Calculate & return a 2 element integer array that specifies the relative 
 	 * weights of the selection area and the edit area, based on the specified
 	 * increase in width of the owning shell.  The point of this method is calculate 
 	 * sash weights such that when the shell gets wider, all of the increase in width
 	 * is given to the edit area (tab folder), and the selection area (tree) stays
 	 * the same width.
 	 */
	protected int[] calculateNewSashWeights(int widthIncrease) {
		int[] newWeights = new int[2];
		newWeights[0] = getSelectionArea().getBounds().width;
		newWeights[1] = getEditArea().getBounds().width + widthIncrease;
		return newWeights;
	}

 	/**
 	 * 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.
 	 */
	private void setShellSize(int width, int height) {
		Rectangle bounds = getShell().getDisplay().getBounds();
		getShell().setSize(Math.min(width, bounds.width), Math.min(height, bounds.height));
	}
	
 	protected void disposeExistingTabs() {
		setDisposingTabs(true);
		TabItem[] oldTabs = getTabFolder().getItems();
		for (int i = 0; i < oldTabs.length; i++) {
			oldTabs[i].dispose();
		} 		
		if (getTabGroup() != null) {
			getTabGroup().dispose();
		}
		setTabGroup(null);
		setTabType(null);
		setDisposingTabs(false);
 	}
 	
 	/**
 	 * Sets the current launch configuration that is being
 	 * displayed/edited.
 	 */
 	protected void setWorkingCopy(ILaunchConfigurationWorkingCopy workingCopy) {
 		fWorkingCopy = workingCopy;
 	}
 	
 	protected boolean isWorkingCopyDirty() {
 		ILaunchConfigurationWorkingCopy workingCopy = getLaunchConfiguration();
 		if (workingCopy == null) {
 			return false;
 		}
 		
 		// Working copy hasn't been saved
 		if (workingCopy.getOriginal() == null) {
 			return true;
 		}
 		
 		// Name has changed.  Normally, this would be caught in the 'contentsEqual'
 		// check below, however there are some circumstances where this fails, such as
 		// when the name is invalid
 		if (isNameDirty()) {
 			return true;
 		}

 		updateWorkingCopyFromPages();
 		ILaunchConfiguration original = workingCopy.getOriginal();
 		return !original.contentsEqual(workingCopy);
 	}
 	
 	/**
 	 * Return <code>true</code> if the name has been modified since the last time it was saved.
 	 */
 	protected boolean isNameDirty() {
 		String currentName = getNameTextWidget().getText().trim();
 		return !currentName.equals(getLastSavedName());
 	}
 	
 	protected void setContext(Object context) {
 		fContext = context;
 	}
 	
 	protected Object getContext() {
 		return fContext;
 	}
 	 	
 	protected void setMode(String mode) {
 		fMode = mode;
 	}
 	
 	/** 
 	 * @see ILaunchConfigurationDialog#getMode()
 	 */
 	public String getMode() {
 		return fMode;
 	}
 	
	/**
	 * Sets the text widget used to display the name
	 * of the configuration being displayed/edited
	 * 
	 * @param widget the text widget used to display the name
	 *  of the configuration being displayed/edited
	 */
	private void setNameTextWidget(Text widget) {
		fNameText = widget;
	}
	
	/**
	 * Returns the text widget used to display the name
	 * of the configuration being displayed/edited
	 * 
	 * @return the text widget used to display the name
	 *  of the configuration being displayed/edited
	 */
	protected Text getNameTextWidget() {
		return fNameText;
	} 
	
 	/**
 	 * Sets the 'apply' button.
 	 * 
 	 * @param button the 'apply' button.
 	 */	
 	private void setApplyButton(Button button) {
 		fApplyButton = button;
 	}
 	
 	/**
 	 * Returns the 'apply' button
 	 * 
 	 * @return the 'apply' button
 	 */
 	protected Button getApplyButton() {
 		return fApplyButton;
 	}	
 	
 	/**
 	 * Sets the 'revert' button.
 	 * 
 	 * @param button the 'revert' button.
 	 */	
 	private void setRevertButton(Button button) {
 		fRevertButton = button;
 	}
 	
 	/**
 	 * Returns the 'revert' button
 	 * 
 	 * @return the 'revert' button
 	 */
 	protected Button getRevertButton() {
 		return fRevertButton;
 	}	
 	
 	private void setDisposingTabs(boolean disposing) {
 		fDisposingTabs = disposing;
 	}
 	
 	private boolean isDisposingTabs() {
 		return fDisposingTabs;
 	}
 
 	/**
 	 * Sets the tab folder
 	 * 
 	 * @param folder the tab folder
 	 */	
 	private void setTabFolder(TabFolder folder) {
 		fTabFolder = folder;
 	}
 	
 	/**
 	 * Returns the tab folder
 	 * 
 	 * @return the tab folder
 	 */
 	protected TabFolder getTabFolder() {
 		return fTabFolder;
 	}	 	
 	
 	/**
 	 * Sets the current tab group being displayed
 	 * 
 	 * @param group the current tab group being displayed
 	 */
 	private void setTabGroup(ILaunchConfigurationTabGroup group) {
 		fTabGroup = group;
 	}
 	
 	/**
 	 * Returns the current tab group
 	 * 
 	 * @return the current tab group, or <code>null</code> if none
 	 */
 	public ILaunchConfigurationTabGroup getTabGroup() {
 		return fTabGroup;
 	}
 	
 	/**
 	 * @see ILaunchConfigurationDialog#getTabs()
 	 */
 	public ILaunchConfigurationTab[] getTabs() {
 		if (getTabGroup() == null) {
 			return null;
 		} else {
 			return getTabGroup().getTabs();
 		}
 	} 	
 	
	/**
	 * @see ILaunchConfigurationListener#launchConfigurationAdded(ILaunchConfiguration)
	 */
	public void launchConfigurationAdded(ILaunchConfiguration configuration) {
		setIgnoreSelectionChanges(true);
		try {
			setWorkingCopy(configuration.getWorkingCopy());
			fUnderlyingConfig = configuration;
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
		}
		getTreeViewer().refresh();	
		updateButtons();
		setIgnoreSelectionChanges(false);
	}

	/**
	 * @see ILaunchConfigurationListener#launchConfigurationChanged(ILaunchConfiguration)
	 */
	public void launchConfigurationChanged(ILaunchConfiguration configuration) {
	}

	/**
	 * @see ILaunchConfigurationListener#launchConfigurationRemoved(ILaunchConfiguration)
	 */
	public void launchConfigurationRemoved(ILaunchConfiguration configuration) {
		getTreeViewer().remove(configuration);		
	}
	
	protected void setIgnoreSelectionChanges(boolean ignore) {
		fIgnoreSelectionChanges = ignore;
	}
	
	protected boolean ignoreSelectionChanges() {
		return fIgnoreSelectionChanges;
	}
	
	/**
	 * Return whether the current configuration can be discarded.  This involves determining
	 * if it is dirty, and if it is, asking the user what to do.
	 */
	protected boolean canDiscardCurrentConfig() {		
		// If there is no working copy, there's no problem, return true
		ILaunchConfigurationWorkingCopy workingCopy = getLaunchConfiguration();
		if (workingCopy == null) {
			return true;
		}
		
		if (isWorkingCopyDirty()) {
			return showUnsavedChangesDialog();
		} else {
			return true;
		}
	}
	
	/**
	 * 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.
	 */
	protected boolean showUnsavedChangesDialog() {
		if (canSaveConfig()) {
			return showSaveChangesDialog();
		} else {
			return showDiscardChangesDialog();
		}
	}
	
	/**
	 * Create and return a dialog that asks the user whether they want to save
	 * unsaved changes.  Return <code>true </code> if they chose to save changes,
	 * <code>false</code> otherwise.
	 */
	protected boolean showSaveChangesDialog() {
		StringBuffer buffer = new StringBuffer(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.The_configuration___29")); //$NON-NLS-1$
		buffer.append(getLaunchConfiguration().getName());
		buffer.append(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.__has_unsaved_changes.__Do_you_wish_to_save_them__30")); //$NON-NLS-1$
		MessageDialog dialog = new MessageDialog(getShell(), 
												 LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Save_changes__31"), //$NON-NLS-1$
												 null,
												 buffer.toString(),
												 MessageDialog.QUESTION,
												 new String[] {LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Yes_32"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.No_33"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cancel_34")}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
												 0);
		// If user clicked 'Cancel' or closed dialog, return false
		int selectedButton = dialog.open();
		if ((selectedButton < 0) || (selectedButton == 2)) {
			return false;
		}
		
		// If they hit 'Yes', save the working copy 
		if (selectedButton == 0) {
			saveConfig();
		}
		
		return true;
	}
	
	/**
	 * Create and return a dialog that asks the user whether they want to discard
	 * unsaved changes.  Return <code>true</code> if they chose to discard changes,
	 * <code>false</code> otherwise.
	 */
	protected boolean showDiscardChangesDialog() {
		StringBuffer buffer = new StringBuffer(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.The_configuration___35")); //$NON-NLS-1$
		buffer.append(getNameTextWidget().getText());
		buffer.append(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.__has_unsaved_changes_that_CANNOT_be_saved_because_of_the_following_error_36")); //$NON-NLS-1$
		buffer.append(fCantSaveErrorMessage);
		buffer.append(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Do_you_wish_to_discard_changes_37")); //$NON-NLS-1$
		MessageDialog dialog = new MessageDialog(getShell(), 
												 LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Discard_changes__38"), //$NON-NLS-1$
												 null,
												 buffer.toString(),
												 MessageDialog.QUESTION,
												 new String[] {LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Yes_32"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.No_33")}, //$NON-NLS-1$ //$NON-NLS-2$
												 1);
		// If user clicked 'Yes', return true
		int selectedButton = dialog.open();
		if (selectedButton == 0) {
			return true;
		}
		return false;
	}
	
	/**
	 * Return <code>true</code> if the current configuration can be saved, <code>false</code>
	 * otherwise.  Note this is NOT the same thing as the config simply being valid.  It is
	 * possible to save a config that does not validate.  This method determines whether the
	 * config can be saved without causing a serious error.  For example, a shared config that
	 * has no specified location would cause this method to return <code>false</code>.
	 */
	protected boolean canSaveConfig() {
		
		fCantSaveErrorMessage = null;

		// First make sure that name doesn't prevent saving the config
		try {
			verifyName();
		} catch (CoreException ce) {
			fCantSaveErrorMessage = ce.getStatus().getMessage();
			return false;
		}
		
		// Next, make sure none of the tabs object to saving the config
		ILaunchConfigurationTab[] tabs = getTabs();
		if (tabs == null) {
			fCantSaveErrorMessage = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.No_tabs_found_41"); //$NON-NLS-1$
			return false;
		}
		for (int i = 0; i < tabs.length; i++) {
			if (!tabs[i].canSave()) {
				fCantSaveErrorMessage = tabs[i].getErrorMessage();
				return false;
			}
		}
		return true;		
	}

	/**
	 * Notification the 'New' action has been activated.
	 */
	protected void handleNewAction() {
		
		// Take care of any unsaved changes
		if (!canDiscardCurrentConfig()) {
			return;
		}
		
		// The 'New' action should only be enabled if a single config type is selected
		Object selectedElement = getTreeViewerFirstSelectedElement();
		if (!(selectedElement instanceof ILaunchConfigurationType)) {
			return;
		}
		
		// Construct a new config of the selected type and select the result in the tree
		ILaunchConfigurationType configType = (ILaunchConfigurationType) selectedElement;
		constructNewConfig(configType);
		getTreeViewer().setSelection(new StructuredSelection(fUnderlyingConfig));		
	}	
	
	/**
	 * Notification the 'Duplicate' action has been activated.
	 */
	protected void handleDuplicateAction() {

		// Take care of any unsaved changes
		if (!canDiscardCurrentConfig()) {
			return;
		}
		
		// The 'Duplicate' action should only be enabled if a single config is selected
		Object selectedElement = getTreeViewerFirstSelectedElement();
		if (!(selectedElement instanceof ILaunchConfiguration)) {
			return;
		}
		
		// Duplicate the selected config and select the dupe in the tree
		ILaunchConfiguration copyFromConfig = (ILaunchConfiguration) selectedElement;
		String newName = getLaunchManager().generateUniqueLaunchConfigurationNameFrom(copyFromConfig.getName());
		try {
			ILaunchConfigurationWorkingCopy newWorkingCopy = copyFromConfig.copy(newName);
			setLaunchConfiguration(newWorkingCopy, false);
			doSave();
			getTreeViewer().setSelection(new StructuredSelection(fUnderlyingConfig));
		} catch (CoreException ce) {
			DebugUIPlugin.log(ce);			
		}							
	}
	
	/**
	 * Create a new configuration of the specified type and select it in the tree.
	 */
	protected void doHandleNewConfiguration(ILaunchConfigurationType configType) {
		constructNewConfig(configType);
		getTreeViewer().setSelection(new StructuredSelection(fUnderlyingConfig));		
	}
	
	/**
	 * Make a copy of the specified configuration and select it in the tree.
	 */
	protected void doHandleCopyConfiguration(ILaunchConfiguration copyFromConfig) {
		String newName = getLaunchManager().generateUniqueLaunchConfigurationNameFrom(copyFromConfig.getName());
		try {
			ILaunchConfigurationWorkingCopy newWorkingCopy = copyFromConfig.copy(newName);
			setLaunchConfiguration(newWorkingCopy, false);
			doSave();
			getTreeViewer().setSelection(new StructuredSelection(fUnderlyingConfig));
		} catch (CoreException ce) {
			DebugUIPlugin.log(ce);			
		}					
	}
	
	/** 
	 * If a config type is selected, create a new config of that type initialized to 
	 * fWorkbenchSelection.  If a config is selected, create of new config of the
	 * same type as the selected config.
	 * protected void constructNewConfig() {
	 */
	protected void constructNewConfig(ILaunchConfigurationType configType) {	
		try {
			ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, getLaunchManager().generateUniqueLaunchConfigurationNameFrom(DEFAULT_NEW_CONFIG_NAME));
			setLastSavedName(null);
			setLaunchConfiguration(wc, true);
			doSave();
		} catch (CoreException ce) {
			DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Error_19"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_creating_new_launch_configuration_45"), ce); //$NON-NLS-1$ //$NON-NLS-2$
 			clearLaunchConfiguration();
 			return;			
		}		
	}
	
	/**
	 * Notification the 'Delete' action has been activated
	 */
	protected void handleDeleteAction() {		
		IStructuredSelection selection = getTreeViewerSelection();
		
		// The 'Delete' button is disabled if the selection contains anything other than configurations (no types)
		ILaunchConfiguration firstSelectedConfig = (ILaunchConfiguration) selection.getFirstElement();
		ILaunchConfigurationType firstSelectedConfigType = null;
		try {
			firstSelectedConfigType = firstSelectedConfig.getType();
		} catch (CoreException ce) {
			DebugUIPlugin.log(ce);						
		}
		
		// Initialize data used to set the selection after deletion
		int typeIndex= -1; // The index of the deleted configuration's type
		int configIndex= -1; // The index of the deleted configuration
		TreeItem[] items= getTreeViewer().getTree().getItems();
		TreeItem typeItem;
		for (int i= 0, numTypes= items.length; i < numTypes; i++) {
			typeItem= items[i];
			if (typeItem.getData() == firstSelectedConfigType) {
				typeIndex= i;
				TreeItem[] configs= typeItem.getItems();
				for (int j= 0, numConfigs= configs.length; j < numConfigs; j++) {
					if (configs[j].getData() == firstSelectedConfig) {
						configIndex= j;
						break;
					}
				}
			}
			
		}

		// Make the user confirm the deletion
		String dialogMessage = selection.size() > 1 ? LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Do_you_wish_to_delete_the_selected_launch_configurations__1") : LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Do_you_wish_to_delete_the_selected_launch_configuration__2"); //$NON-NLS-1$ //$NON-NLS-2$
		boolean ok = MessageDialog.openQuestion(this.getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Confirm_Launch_Configuration_Deletion_3"), dialogMessage); //$NON-NLS-1$
		if (!ok) {
			return;
		}


		Iterator iterator = selection.iterator();
		while (iterator.hasNext()) {
			clearLaunchConfiguration();
			Object selectedElement = iterator.next();
			if (selectedElement instanceof ILaunchConfiguration) {
				try {
					((ILaunchConfiguration)selectedElement).delete();
				} catch (CoreException ce) {
					DebugUIPlugin.log(ce);			
				}
			}
		}
		
		IStructuredSelection newSelection= null;
		if (typeIndex != -1 && configIndex != -1) {
			// Reset selection to the next config
			TreeItem[] configItems= getTreeViewer().getTree().getItems()[typeIndex].getItems();
			int numItems= configItems.length;
			if (numItems > configIndex) { // Select the item at the same index as the deleted
				newSelection= new StructuredSelection(configItems[configIndex].getData());
			} else if (numItems > 0) { // Deleted the last item(s). Select the last item
				newSelection= new StructuredSelection(configItems[numItems - 1].getData());
			}
		} 
		if (newSelection == null) {
			// Reset selection to the config type of the first selected configuration
			newSelection = new StructuredSelection(firstSelectedConfigType);
		}
		getTreeViewer().setSelection(newSelection);
	}	
	
	/**
	 * Notification the 'Close' button has been pressed.
	 */
	protected void handleClosePressed() {
		if (canDiscardCurrentConfig()) {
			disposeExistingTabs();
			cancelPressed();
		}
	}
	
	/**
	 * Notification that the 'Apply' button has been pressed
	 */
	protected void handleApplyPressed() {
		saveConfig();
		getTreeViewer().setSelection(new StructuredSelection(fUnderlyingConfig));
	}
	
	/**
	 * Notification that the 'Revert' button has been pressed
	 */
	protected void handleRevertPressed() {
		setLaunchConfiguration(getLaunchConfiguration().getOriginal(), false);
	}
	
	protected void saveConfig() {
		try {
			// trim name
			Text widget = getNameTextWidget();
			widget.setText(widget.getText().trim());
			doSave();
		} catch (CoreException e) {
			DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configuration_Error_46"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_while_saving_launch_configuration_47"), e); //$NON-NLS-1$ //$NON-NLS-2$
			return;
		}
		
		updateButtons();		
	}
	
	/**
	 * Notification that a tab has been selected
	 * 
	 * Disallow tab changing when the current tab is invalid.
	 * Update the config from the tab being left, and refresh
	 * the tab being entered.
	 */
	protected void handleTabSelected() {
		if (isDisposingTabs()) {
			return;
		}
		ILaunchConfigurationTab[] tabs = getTabs();
		if (fCurrentTabIndex == getTabFolder().getSelectionIndex() || tabs == null || tabs.length == 0 || fCurrentTabIndex > (tabs.length - 1)) {
			return;
		}
		if (fCurrentTabIndex != -1) {
			ILaunchConfigurationTab tab = tabs[fCurrentTabIndex];
			ILaunchConfigurationWorkingCopy wc = getLaunchConfiguration();
			if (wc != null) {
				// apply changes when leaving a tab
				tab.performApply(getLaunchConfiguration());
				// re-initialize a tab when entering it
				getActiveTab().initializeFrom(wc);
			}
		}
		fCurrentTabIndex = getTabFolder().getSelectionIndex();
		refreshStatus();
	}	
	
	/**
	 * Iterate over the pages to update the working copy
	 */
	protected void updateWorkingCopyFromPages() {
		ILaunchConfigurationWorkingCopy workingCopy = getLaunchConfiguration();
		if (getTabGroup() != null) {
			getTabGroup().performApply(workingCopy);
		}
	}
	
	/**
	 * Do the save
	 */
	protected void doSave() throws CoreException {
		ILaunchConfigurationWorkingCopy workingCopy = getLaunchConfiguration();
		updateWorkingCopyFromPages();
		if (isWorkingCopyDirty()) {
			fUnderlyingConfig = workingCopy.doSave();
			setWorkingCopy(fUnderlyingConfig.getWorkingCopy());
			setLastSavedName(fUnderlyingConfig.getName()); 
		}
	}
	
	/**
	 * Notification the 'launch' button has been pressed.
	 * Save and launch.
	 */
	protected void handleLaunchPressed() {
		int result = CANCEL;
		try {
			doSave();
			result = doLaunch(getLaunchConfiguration());
		} catch (CoreException e) {
			DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configuration_Error_6"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_while_launching_configuration._See_log_for_more_information_49"), e); //$NON-NLS-1$ //$NON-NLS-2$
			return;
		}
		if (result == OK) {
			if (fUnderlyingConfig != null) {
				try {
					getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAST_LAUNCH_CONFIGURATION_SELECTION, fUnderlyingConfig.getMemento());
				} catch (CoreException e) {
					DebugUIPlugin.log(e);
				}
			}
			disposeExistingTabs();
			close();
		} else {
			getShell().setFocus();
		}
	}
	
	/**
	 * Save the working copy if necessary, then launch the underlying configuration.
	 * 
	 * @return one of CANCEL or OK
	 */
	protected int doLaunch(ILaunchConfiguration config) throws CoreException {
		
		if (!DebugUITools.saveAndBuildBeforeLaunch()) {
			return CANCEL;
		}
		
		// If the configuration is a working copy and is dirty or doesn't yet exist, save it
		if (config instanceof ILaunchConfigurationWorkingCopy) {
			ILaunchConfigurationWorkingCopy workingCopy = (ILaunchConfigurationWorkingCopy) config;
			if (isWorkingCopyDirty() || !workingCopy.exists()) {
				fUnderlyingConfig = workingCopy.doSave();
			} 
		}
		
		// liftoff
		ILaunch launch = launchWithProgress();
		
		// If the launch was cancelled, get out.  Otherwise, notify the tabs of the successful launch.
		if (cancelButtonPressed()) {
			launch.terminate();
			return CANCEL;
		} else if (launch != null) {
			ILaunchConfigurationTabGroup group = getTabGroup();
			boolean disposeTabs = false;
			if (group == null) {
				// when launching without realizing this dialog, the tabs
				// may not exist - create and then dispose so we can notify them of a launch
				disposeTabs = true;
				group = createGroup(config.getType());
			}
			group.launched(launch);
			if (disposeTabs) {
				group.dispose();
			}
		}
		
		return OK;
	}
	
	/**
	 * @return the resulting launch, or <code>null</code> if cancelled.
	 * @exception CoreException if an exception occurrs launching
	 */
	private ILaunch launchWithProgress() throws CoreException {
		final ILaunch[] launchResult = new ILaunch[1];
		// Do the launch
		IRunnableWithProgress runnable = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException {
				try {
					launchResult[0] = fUnderlyingConfig.launch(getMode(), monitor);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				}
			}
		};
		try {
			run(true, true, runnable);
		} catch (InterruptedException e) {
			return null;
		} catch (InvocationTargetException e) {
			Throwable t = e.getTargetException();
			if (t instanceof CoreException) {
				throw (CoreException)t;
			} else {
				IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, DebugException.INTERNAL_ERROR, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_while_launching_50"), t); //$NON-NLS-1$
				throw new CoreException(status);
			}
		} finally {
			//remove any "error" launch
			ILaunchManager manager= DebugPlugin.getDefault().getLaunchManager();
			ILaunch[] launches= manager.getLaunches();
			for (int i = 0; i < launches.length; i++) {
				ILaunch iLaunch = launches[i];
				if (!iLaunch.hasChildren()) {
					manager.removeLaunch(iLaunch);
				}
			}
		}
				
		return launchResult[0];		
	}
	
	protected IPreferenceStore getPreferenceStore() {
		return DebugUIPlugin.getDefault().getPreferenceStore();
	}

	/***************************************************************************************
	 * 
	 * ProgressMonitor & IRunnableContext related methods
	 * 
	 ***************************************************************************************/

	/**
	 * @see IRunnableContext#run(boolean, boolean, IRunnableWithProgress)
	 */
	public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
		if (isVisible()) {
			// The operation can only be canceled if it is executed in a separate thread.
			// Otherwise the UI is blocked anyway.
			Object state = aboutToStart();
			fActiveRunningOperations++;
			try {
				ModalContext.run(runnable, fork, fProgressMonitorPart, getShell().getDisplay());
			} finally {
				fActiveRunningOperations--;
				stopped(state);
			}
		} else {
			ProgressMonitorDialog dialog = new ProgressMonitorDialog(DebugUIPlugin.getShell());
			dialog.run(fork, cancelable, runnable);
		}
	}
	
	/**
	 * About to start a long running operation triggered through
	 * the dialog. Shows the progress monitor and disables the dialog's
	 * buttons and controls.
	 *
	 * @return the saved UI state
	 */
	private Object aboutToStart() {
		Map savedState = null;
		if (getShell() != null) {
			// Save focus control
			Control focusControl = getShell().getDisplay().getFocusControl();
			if (focusControl != null && focusControl.getShell() != getShell()) {
				focusControl = null;
			}
			
			// Set the busy cursor to all shells.
			Display d = getShell().getDisplay();
			waitCursor = new Cursor(d, SWT.CURSOR_WAIT);
			setDisplayCursor(waitCursor);
					
			// Set the arrow cursor to the cancel component.
			arrowCursor= new Cursor(d, SWT.CURSOR_ARROW);
			getProgressMonitorCancelButton().setCursor(arrowCursor);
	
			// Deactivate shell
			savedState = saveUIState();
			if (focusControl != null) {
				savedState.put(FOCUS_CONTROL, focusControl);
			}
				
			// Attach the progress monitor part to the cancel button
			getProgressMonitorCancelButton().setEnabled(true);
			setCancelButtonPressed(false);
			getProgressMonitorPart().attachToCancelComponent(getProgressMonitorCancelButton());
			getProgressMonitorPart().setVisible(true);
			getProgressMonitorCancelButton().setFocus();
		}
		return savedState;
	}

	/**
	 * A long running operation triggered through the dialog
	 * was stopped either by user input or by normal end.
	 * Hides the progress monitor and restores the enable state
	 * of the dialog's buttons and controls.
	 *
	 * @param savedState the saved UI state as returned by <code>aboutToStart</code>
	 * @see #aboutToStart
	 */
	private void stopped(Object savedState) {
		if (getShell() != null) {
			getProgressMonitorPart().setVisible(false);
			getProgressMonitorPart().removeFromCancelComponent(getProgressMonitorCancelButton());
			Map state = (Map)savedState;
			restoreUIState(state);
	
			setDisplayCursor(null);	
			waitCursor.dispose();
			waitCursor = null;
			arrowCursor.dispose();
			arrowCursor = null;
			Control focusControl = (Control)state.get(FOCUS_CONTROL);
			if (focusControl != null) {
				focusControl.setFocus();
			}
		}
	}

	/**
	 * Captures and returns the enabled/disabled state of the wizard dialog's
	 * buttons and the tree of controls for the currently showing page. All
	 * these controls are disabled in the process, with the possible excepton of
	 * the Cancel button.
	 *
	 * @return a map containing the saved state suitable for restoring later
	 *   with <code>restoreUIState</code>
	 * @see #restoreUIState
	 */
	private Map saveUIState() {
		Map savedState= new HashMap(10);
		saveEnableStateAndSet(getButtonActionNew().getButton(), savedState, "new", false);//$NON-NLS-1$
		saveEnableStateAndSet(getButtonActionDelete().getButton(), savedState, "delete", false);//$NON-NLS-1$
		saveEnableStateAndSet(getApplyButton(), savedState, "apply", false);//$NON-NLS-1$
		saveEnableStateAndSet(getRevertButton(), savedState, "revert", false);//$NON-NLS-1$
		saveEnableStateAndSet(getButton(ID_LAUNCH_BUTTON), savedState, "launch", false);//$NON-NLS-1$
		saveEnableStateAndSet(getButton(ID_CLOSE_BUTTON), savedState, "close", false);//$NON-NLS-1$
		savedState.put("editarea", ControlEnableState.disable(getEditArea()));//$NON-NLS-1$
		savedState.put("tree", ControlEnableState.disable(getTreeViewer().getControl()));//$NON-NLS-1$
		return savedState;
	}

	/**
	 * Saves the enabled/disabled state of the given control in the
	 * given map, which must be modifiable.
	 *
	 * @param w the control, or <code>null</code> if none
	 * @param h the map (key type: <code>String</code>, element type:
	 *   <code>Boolean</code>)
	 * @param key the key
	 * @param enabled <code>true</code> to enable the control, 
	 *   and <code>false</code> to disable it
	 * @see #restoreEnableStateAndSet
	 */
	private void saveEnableStateAndSet(Control w, Map h, String key, boolean enabled) {
		if (w != null) {
			h.put(key, new Boolean(w.isEnabled()));
			w.setEnabled(enabled);
		}
	}

	/**
	 * Restores the enabled/disabled state of the wizard dialog's
	 * buttons and the tree of controls for the currently showing page.
	 *
	 * @param state a map containing the saved state as returned by 
	 *   <code>saveUIState</code>
	 * @see #saveUIState
	 */
	private void restoreUIState(Map state) {
		restoreEnableState(getButtonActionNew().getButton(), state, "new");//$NON-NLS-1$
		restoreEnableState(getButtonActionDelete().getButton(), state, "delete");//$NON-NLS-1$
		restoreEnableState(getApplyButton(), state, "apply");//$NON-NLS-1$
		restoreEnableState(getRevertButton(), state, "revert");//$NON-NLS-1$
		restoreEnableState(getButton(ID_LAUNCH_BUTTON), state, "launch");//$NON-NLS-1$
		restoreEnableState(getButton(ID_CLOSE_BUTTON), state, "close");//$NON-NLS-1$
		ControlEnableState tabState = (ControlEnableState) state.get("editarea");//$NON-NLS-1$
		tabState.restore();
		ControlEnableState treeState = (ControlEnableState) state.get("tree");//$NON-NLS-1$
		treeState.restore();		
	}

	/**
	 * Restores the enabled/disabled state of the given control.
	 *
	 * @param w the control
	 * @param h the map (key type: <code>String</code>, element type:
	 *   <code>Boolean</code>)
	 * @param key the key
	 * @see #saveEnableStateAndSet
	 */
	private void restoreEnableState(Control w, Map h, String key) {
		if (w != null) {
			Boolean b = (Boolean) h.get(key);
			if (b != null)
				w.setEnabled(b.booleanValue());
		}
	}
	
	protected void setCancelButtonPressed(boolean pressed) {
		fCancelButtonPressed = pressed;
	}
	
	protected boolean cancelButtonPressed() {
		return fCancelButtonPressed;
	}

	/**
	 * Sets the given cursor for all shells currently active
	 * for this window's display.
	 *
	 * @param cursor the cursor
	 */
	private void setDisplayCursor(Cursor cursor) {
		Shell[] shells = getShell().getDisplay().getShells();
		for (int i = 0; i < shells.length; i++)
			shells[i].setCursor(cursor);
	}
	
	/**
	 * Checks whether it is alright to close this dialog
	 * and performed standard cancel processing. If there is a
	 * long running operation in progress, this method posts an
	 * alert message saying that the dialog cannot be closed.
	 * 
	 * @return <code>true</code> if it is alright to close this dialog, and
	 *  <code>false</code> if it is not
	 */
	private boolean okToClose() {
		if (fActiveRunningOperations > 0) {
			synchronized (this) {
				fWindowClosingDialog = createDialogClosingDialog();
			}	
			fWindowClosingDialog.open();
			synchronized (this) {
				fWindowClosingDialog = null;
			}
			return false;
		}
		
		return true;
	}

	/**
	 * Creates and return a new wizard closing dialog without opening it.
	 */ 
	private MessageDialog createDialogClosingDialog() {
		MessageDialog result= new MessageDialog(
			getShell(),
			JFaceResources.getString("WizardClosingDialog.title"),//$NON-NLS-1$
			null,
			JFaceResources.getString("WizardClosingDialog.message"),//$NON-NLS-1$
			MessageDialog.QUESTION,
			new String[] {IDialogConstants.OK_LABEL},
			0 ); 
		return result;
	}
	
	/**
	 * @see ILaunchConfigurationDialog#canLaunch()
	 */
	public boolean canLaunch() {
		try {
			verifyStandardAttributes();
		} catch (CoreException e) {
			return false;
		}
		
		ILaunchConfigurationTab[] tabs = getTabs();
		if (tabs == null) {
			return false;
		}
		for (int i = 0; i < tabs.length; i++) {
			if (!tabs[i].isValid(getLaunchConfiguration())) {
				return false;
			}
		}
		return true;
	}

	protected ILaunchConfigurationWorkingCopy getLaunchConfiguration() {
		return fWorkingCopy;
	}

	/**
	 * @see ILaunchConfigurationDialog#updateButtons()
	 */
	public void updateButtons() {
		if (isInitializingTabs()) {
			return;
		}
		
		// Get the current selection
		IStructuredSelection sel = (IStructuredSelection)getTreeViewer().getSelection();
		boolean singleSelection = sel.size() == 1;
		boolean firstItemLaunchConfig = sel.getFirstElement() instanceof ILaunchConfiguration;
		boolean firstItemLaunchConfigType = sel.getFirstElement() instanceof ILaunchConfigurationType;
		
		// New action
 		getButtonActionNew().setEnabled(singleSelection && firstItemLaunchConfigType);
		
		// Duplicate action
		getButtonActionDuplicate().setEnabled(singleSelection && firstItemLaunchConfig);
		
		// Delete action
		if (sel.isEmpty()) {
			getButtonActionDelete().setEnabled(false); 		
		} else {
			Iterator iter = sel.iterator();
			boolean enable = true;
			while (iter.hasNext()) {
				if (iter.next() instanceof ILaunchConfigurationType) {
					enable = false;
					break;
				}
			}
			getButtonActionDelete().setEnabled(enable);
		}
		

		// Apply & Launch buttons
		if (sel.isEmpty()) {
			getApplyButton().setEnabled(false);
			getButton(ID_LAUNCH_BUTTON).setEnabled(false);
		} else {
			boolean canLaunch = canLaunch();
			getApplyButton().setEnabled(canLaunch);
			getButton(ID_LAUNCH_BUTTON).setEnabled(canLaunch);		
		}
		
		// Revert button
		if (sel.isEmpty() || sel.size() > 1) {
			getRevertButton().setEnabled(false);
		} else {
			if (firstItemLaunchConfig && isWorkingCopyDirty()) {
				getRevertButton().setEnabled(true);
			} else {
				getRevertButton().setEnabled(false);
			}
		}
	}
	
	/**
	 * @see ILaunchConfigurationDialog#getActiveTab()
	 */
	public ILaunchConfigurationTab getActiveTab() {
		TabFolder folder = getTabFolder();
		ILaunchConfigurationTab[] tabs = getTabs();
		if (folder != null && tabs != null) {
			int pageIndex = folder.getSelectionIndex();
			if (pageIndex >= 0) {		
				return tabs[pageIndex];		
			}
		}
		return null;
	}
	
	/**
	 * Returns the currently active TabItem
	 * 
	 * @return launch configuration tab item
	 */
	protected TabItem getActiveTabItem() {
		TabFolder folder = getTabFolder();
		TabItem tabItem = null;
		int selectedIndex = folder.getSelectionIndex();
		if (selectedIndex >= 0) {
			tabItem = folder.getItem(selectedIndex);
		}		
		return tabItem;
	}

	/**
	 * @see ILaunchConfigurationDialog#updateMessage()
	 */
	public void updateMessage() {
		if (isInitializingTabs()) {
			return;
		}
		
		// If there is no current working copy, show a default informational message and clear the error message
		if (getLaunchConfiguration() == null) {
			setErrorMessage(null);
			setMessage(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Select_a_type_of_configuration_to_create,_and_press___new__51")); //$NON-NLS-1$
			return;
		}
		
		try {
			verifyStandardAttributes();
		} catch (CoreException ce) {
			setErrorMessage(ce.getMessage());
			return;
		}
		
		// Get the active tab.  If there isn't one, clear the informational & error messages
		ILaunchConfigurationTab activeTab = getActiveTab();
		if (activeTab == null) {
			setMessage(null);
			setErrorMessage(null);
			return;
		}
		
		// Always set the informational (non-error) message based on the active tab		
		setMessage(activeTab.getMessage());
		
		// The bias is to show the active page's error message, but if there isn't one,
		// show the error message for one of the other tabs that has an error.  Set the icon
		// for all tabs according to whether they contain errors.
		String errorMessage = checkTabForError(activeTab);
		boolean errorOnActiveTab = errorMessage != null;
		setTabIcon(getActiveTabItem(), errorOnActiveTab, activeTab);
		
		ILaunchConfigurationTab[] allTabs = getTabs();
		for (int i = 0; i < allTabs.length; i++) {
			if (getTabFolder().getSelectionIndex() == i) {
				continue;
			}
			String tabError = checkTabForError(allTabs[i]);				
			TabItem tabItem = getTabFolder().getItem(i);
			boolean errorOnTab = tabError != null;
			setTabIcon(tabItem, errorOnTab, allTabs[i]);
			if (errorOnTab && !errorOnActiveTab) {
				errorMessage = '[' + removeAmpersandsFrom(tabItem.getText()) + "]: " + tabError; //$NON-NLS-1$
			}
		}
		setErrorMessage(errorMessage);				
	}
	
	/**
	 * Force the tab to update it's error state and return any error message.
	 */
	protected String checkTabForError(ILaunchConfigurationTab tab) {
		tab.isValid(getLaunchConfiguration());
		return tab.getErrorMessage();
	}
	
	/**
	 * Set the specified tab item's icon to an error icon if <code>error</code> is true,
	 * or a transparent icon of the same size otherwise.
	 */
	protected void setTabIcon(TabItem tabItem, boolean error, ILaunchConfigurationTab tab) {
		Image image = null;
		if (error) {			
			image = LaunchConfigurationManager.getDefault().getErrorTabImage(tab);
		} else {
			image = tab.getImage();
		}
		tabItem.setImage(image);								
	}
	
	/**
	 * Return a copy of the specified string 
	 */
	protected String removeAmpersandsFrom(String string) {
		String newString = new String(string);
		int index = newString.indexOf('&');
		while (index != -1) {
			newString = string.substring(0, index) + newString.substring(index + 1, newString.length());
			index = newString.indexOf('&');
		}
		return newString;
	}

	/**
	 * Returns the launch configuration selection area control.
	 * 
	 * @return control
	 */
	protected Composite getSelectionArea() {
		return fSelectionArea;
	}

	/**
	 * Sets the launch configuration selection area control.
	 * 
	 * @param editArea control
	 */
	private void setSelectionArea(Composite selectionArea) {
		fSelectionArea = selectionArea;
	}

	/**
	 * Returns the launch configuration edit area control.
	 * 
	 * @return control
	 */
	protected Composite getEditArea() {
		return fEditArea;
	}

	/**
	 * Sets the launch configuration edit area control.
	 * 
	 * @param editArea control
	 */
	private void setEditArea(Composite editArea) {
		fEditArea = editArea;
	}

	/**
	 * Returns the type that tabs are currently displayed
	 * for, or <code>null</code> if none.
	 * 
	 * @return launch configuration type or <code>null</code>
	 */
	protected ILaunchConfigurationType getTabType() {
		return fTabType;
	}

	/**
	 * Sets the type that tabs are currently displayed
	 * for, or <code>null</code> if none.
	 * 
	 * @param tabType launch configuration type
	 */
	private void setTabType(ILaunchConfigurationType tabType) {
		fTabType = tabType;
	}

	protected Object getSelectedTreeObject() {
		return fSelectedTreeObject;
	}
	
	protected void setSelectedTreeObject(Object obj) {
		fSelectedTreeObject = obj;
	}	
	
	/**
	 * @see ILaunchConfigurationDialog#setName(String)
	 */
	public void setName(String name) {
		if (isVisible()) {
			if (name == null) {
				name = ""; //$NON-NLS-1$
			}
			fNameText.setText(name.trim());
			refreshStatus();
		}
	}
	
	/**
	 * @see ILaunchConfigurationDialog#generateName(String)
	 */
	public String generateName(String name) {
		if (name == null) {
			name = ""; //$NON-NLS-1$
		}
		return getLaunchManager().generateUniqueLaunchConfigurationNameFrom(name);
	}

	/**
	 * @see IDoubleClickListener#doubleClick(DoubleClickEvent)
	 */
	public void doubleClick(DoubleClickEvent event) {		
		ISelection selection = event.getSelection();		
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection structuredSelection = (IStructuredSelection) selection;
			Object firstSelected = structuredSelection.getFirstElement();
			if (firstSelected instanceof ILaunchConfigurationType) {
				if (getButtonActionNew().isEnabled()) {
					getButtonActionNew().run();
				}
			} else if (firstSelected instanceof ILaunchConfiguration) {
				if (canLaunch()) {
					handleLaunchPressed();
				}				
			}
		}		
	}
	
	/**
	 * Sets whether this dialog is initializing pages
	 * and should not bother to refresh status (butttons
	 * and message).
	 */
	private void setInitializingTabs(boolean init) {
		fInitializingTabs = init;
	}
	
	/**
	 * Returns whether this dialog is initializing pages
	 * and should not bother to refresh status (butttons
	 * and message).
	 */
	protected boolean isInitializingTabs() {
		return fInitializingTabs;
	}	
	
	/**
	 * Returns the initial launch configuration type, or <code>null</code> if none has been set.
	 */
	protected ILaunchConfigurationType getInitialConfigType() {
		return fInitialConfigType;
	}
	
	/**
	 * Sets the initial launch configuration type to be used when this dialog is opened.
	 */
	public void setInitialConfigType(ILaunchConfigurationType configType) {
		fInitialConfigType = configType;
	}
	
	/**
	 * Returns the initial selection shown in this dialog when opened in
	 * <code>LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION</code> mode.
	 */
	protected IStructuredSelection getInitialSelection() {
		return fInitialSelection;
	}
	
	/**
	 * 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;
	}
	
	/**
	 * Handles key events in tree viewer. Specifically
	 * when the delete key is pressed.
	 */
	protected void handleKeyPressed(KeyEvent event) {
		if (event.character == SWT.DEL && event.stateMask == 0) {
			if (getButtonActionDelete().isEnabled()) {
				getButtonActionDelete().run();
			}
		}
	}
	
	protected void setButtonActionNew(ButtonAction action) {
		fButtonActionNew = action;
	}
	
	protected ButtonAction getButtonActionNew() {
		return fButtonActionNew;
	}

	protected void setButtonActionDuplicate(ButtonAction action) {
		fButtonActionDuplicate = action;
	}
	
	protected ButtonAction getButtonActionDuplicate() {
		return fButtonActionDuplicate;
	}

	protected void setButtonActionDelete(ButtonAction action) {
		fButtonActionDelete = action;
	}
	
	protected ButtonAction getButtonActionDelete() {
		return fButtonActionDelete;
	}

	/**
	 * Extension of <code>Action</code> that manages a <code>Button</code>
	 * widget.  This allows common handling for actions that must appear in
	 * a pop-up menu and also as a (non-toolbar) button in the UI.
	 */
	private abstract class ButtonAction extends Action {
		
		protected Button fButton;
		
		/**
		 * Construct a ButtonAction handler.  All details of the specified
		 * <code>Button</code>'s layout and appearance should be handled 
		 * external to this class.
		 */
		public ButtonAction(String text, Button button) {
			super(text);
			fButton = button;
			if (fButton != null) {
				fButton.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent evt) {
						ButtonAction.this.run();
					}
				});
			}
		}
		
		public Button getButton() {
			return fButton;
		}
		
		/**
		 * @see IAction#setEnabled(boolean)
		 */
		public void setEnabled(boolean enabled) {
			super.setEnabled(enabled);
			if (fButton != null) {
				fButton.setEnabled(enabled);
			}
		}
	}
	
	/**
	 * Handler for creating a new configuration.
	 */
	private class ButtonActionNew extends ButtonAction {
		
		public ButtonActionNew(String text, Button button) {
			super(text, button);
		}
		
		public void run() {
			handleNewAction();
		}
	}

	/**
	 * Handler for duplicating a configuration.
	 */
	private class ButtonActionDuplicate extends ButtonAction {
		
		public ButtonActionDuplicate(String text, Button button) {
			super(text, button);
		}
		
		public void run() {
			handleDuplicateAction();
		}
	}

	/**
	 * Handler for deleting a configuration.
	 */
	private class ButtonActionDelete extends ButtonAction {
		
		public ButtonActionDelete(String text, Button button) {
			super(text, button);
		}
		
		public void run() {
			handleDeleteAction();
		}
	}

}