/*******************************************************************************
 * Copyright (c) 2007, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.ui.contextlaunching;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.ILaunchHistoryChangedListener;
import org.eclipse.debug.internal.ui.ILaunchLabelChangedListener;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
import org.eclipse.debug.ui.ILaunchGroup;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.ToolBarContributionItem;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.activities.WorkbenchActivityHelper;
import org.eclipse.ui.internal.WorkbenchWindow;

import com.ibm.icu.text.MessageFormat;

/**
 * This manager is used to calculate the labels for the current resource or for the current
 * state of the launch history, depending on the enabled status of contextual launching. More specifically
 * if contextual launching is enabled the calculated labels are for the current resource, otherwise
 * the calculated labels are for the current state of the launch history.
 *
 * Any actions interested in being notified of launch label updates need to register with this manager, and implement
 * the <code>ILaunchLabelChangedListener</code> interface.
 *
 * @see ILaunchLabelChangedListener
 * @see org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction
 *
 * @since 3.3
 */
@SuppressWarnings("restriction")
public class LaunchingResourceManager implements IPropertyChangeListener, IWindowListener, ISelectionListener, ILaunchHistoryChangedListener, ILaunchesListener2 {

	/**
	 *The set of label update listeners
	 */
	private ListenerList<ILaunchLabelChangedListener> fLabelListeners = new ListenerList<>();

	/**
	 * The map of ToolBars that have mouse tracker listeners associated with them:
	 * stored as Map<IWorkbenchWindow, ToolBar>
	 */
	private HashMap<IWorkbenchWindow, ToolBar> fToolbars = new HashMap<>();

	/**
	 * the map of current labels
	 */
	private HashMap<ILaunchGroup, String> fCurrentLabels = new HashMap<>();

	/**
	 * The selection has changed and we need to update the labels
	 */
	private boolean fUpdateLabel = true;

	/**
	 * Set of windows that have been opened and that we have registered selection listeners with
	 */
	private HashSet<IWorkbenchWindow> fWindows = new HashSet<>();

	/**
	 * Cache of IResource -> ILaunchConfiguration[] used during a tooltip update job.
	 * The cache is cleared after each tooltip update job is complete.
	 */
	private HashMap<IResource, ILaunchConfiguration[]> fConfigCache = new HashMap<>();

	/**
	 * Cache of IResource -> LaunchShortcutExtension used during a tooltip update job.
	 * The cache is cleared after each tooltip update job is complete.
	 */
	private HashMap<IResource, List<LaunchShortcutExtension>> fExtCache = new HashMap<>();

	/**
	 * Constant denoting the empty string;
	 */
	private static final String EMPTY_STRING = IInternalDebugCoreConstants.EMPTY_STRING;

	/**
	 * Provides a mouse tracker listener for the launching main toolbar
	 */
	private MouseTrackAdapter fMouseListener = new MouseTrackAdapter() {
		@Override
		public void mouseEnter(MouseEvent e) {
			if(fUpdateLabel) {
				fUpdateLabel = false;
				fCurrentLabels.clear();
				Job job = new Job("Compute launch button tooltip") { //$NON-NLS-1$
					@Override
					protected IStatus run(IProgressMonitor monitor) {
						computeLabels();
						fConfigCache.clear();
						fExtCache.clear();
						return Status.OK_STATUS;
					}
				};
				job.setSystem(true);
				job.schedule();
			}
		}
	};

	/**
	 * Returns if context launching is enabled
	 * @return if context launching is enabled
	 */
	public static boolean isContextLaunchEnabled() {
		return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_USE_CONTEXTUAL_LAUNCH);
	}

	/**
	 * Returns if context launching is enabled or not. Context launching is enabled iff:
	 * <ul>
	 * <li>The preference is turned on</li>
	 * <li>the launch group id is not <code>org.eclipse.ui.externaltools.launchGroup</code></li>
	 * </ul>
	 * @param launchgroupid the id of the {@link ILaunchGroup}
	 * @return <code>true</code> if context launching is enabled <code>false</code> otherwise
	 */
	public static boolean isContextLaunchEnabled(String launchgroupid) {
		return isContextLaunchEnabled() && !"org.eclipse.ui.externaltools.launchGroup".equals(launchgroupid); //$NON-NLS-1$
	}

	/**
	 * Allows an <code>AbstractLaunchHistoryAction</code> to register with this manager to be notified
	 * of a context (<code>IResource</code>) change and have its updateToolTip(..) method called back to.
	 * <br><br>
	 * Obeys the contract of listener addition as outlined in {@link ListenerList#add(Object)}
	 * @param listener the {@link ILaunchLabelChangedListener} to add
	 */
	public void addLaunchLabelUpdateListener(ILaunchLabelChangedListener listener) {
		fLabelListeners.add(listener);
	}

	/**
	 * Removes the specified <code>AbstractLaunchHistoryAction</code> from the listing of registered
	 * listeners
	 * <br><br>
	 * Obeys the contract of listener removal as outlined in {@link ListenerList#remove(Object)}
	 * @param listener the {@link ILaunchLabelChangedListener} to remove
	 */
	public void removeLaunchLabelChangedListener(ILaunchLabelChangedListener listener) {
		fLabelListeners.remove(listener);
	}

	/**
	 * Returns the current resource label to be displayed.
	 *
	 * @param group the launch group to get the label for
	 * @return the current resource label;
	 */
	public String getLaunchLabel(ILaunchGroup group) {
		return fCurrentLabels.get(group);
	}

	/**
	 * Returns if the parent project should be checked automatically
	 * @return true if the parent project should checked automatically, false otherwise
	 */
	protected boolean shouldCheckParent() {
		return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_PARENT_PROJECT);
	}

	/**
	 * Returns if the the last launch configuration should be launched if the selected resource is not launchable and context launching is enabled
	 * @return true if the last launched should be launched, false otherwise
	 */
	protected boolean shouldLaunchLast() {
		return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE);
	}

	/**
	 * Computes the current listing of labels for the given <code>IResource</code> context change or the
	 * current launch history changed event
	 */
	protected void computeLabels() {
		ILaunchGroup group = null;
		ILaunchConfiguration config = null;
		String label = null;

		SelectedResourceManager srm = SelectedResourceManager.getDefault();
		IStructuredSelection selection = srm.getCurrentSelection();
		List<LaunchShortcutExtension> shortcuts = null;
		IResource resource = srm.getSelectedResource();
		for (ILaunchLabelChangedListener iLaunchLabelChangedListener : fLabelListeners) {
			group = iLaunchLabelChangedListener.getLaunchGroup();
			if(group != null) {
				if(isContextLaunchEnabled(group.getIdentifier())) {
					shortcuts = getShortcutsForSelection(selection, group.getMode());
					if(resource == null) {
						resource = getLaunchableResource(shortcuts, selection);
					}
					label = getLabel(selection, resource, shortcuts, group);
				}
				else {
					config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
					if(config != null) {
						label = appendLaunched(config);
					}
				}
				fCurrentLabels.put(group, label);
				label = null;
			}
		}
		notifyLabelChanged();
	}

	/**
	 * Notifies all registered listeners that the known labels have changed
	 */
	protected void notifyLabelChanged() {
		for (ILaunchLabelChangedListener iLaunchLabelChangedListener : fLabelListeners) {
			iLaunchLabelChangedListener.labelChanged();
		}
	}

	/**
	 * Appends the text '(already running)' to the tooltip label if there is a launch currently
	 * running (not terminated) with the same backing launch configuration as the one specified
	 * @param config the {@link ILaunchConfiguration} to check for running state
	 * @return the appended string for the tooltip label or the configuration name (default)
	 */
	private String appendLaunched(ILaunchConfiguration config) {
		ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
		boolean launched = false;
		ILaunchConfiguration tmp = null;
		for(int i = 0; i < launches.length; i++) {
			tmp = launches[i].getLaunchConfiguration();
			if(tmp != null) {
				if(!launches[i].isTerminated() && tmp.equals(config)) {
					launched = true;
					break;
				}
			}
		}
		if(launched) {
			return MessageFormat.format(ContextMessages.LaunchingResourceManager_0, new Object[] { config.getName() });
		}
		return config.getName();
	}

	/**
	 * Returns the label for the last launched configuration or and empty string if there was no last launch.
	 * @param group the {@link ILaunchGroup} to get the label for
	 * @return the name of the last launched configuration, altered with '(running)' if needed, or the empty
	 * string if there is no last launch.
	 */
	protected String getlastLaunchedLabel(ILaunchGroup group) {
		ILaunchConfiguration config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
		if(config != null) {
			return appendLaunched(config);
		}
		return EMPTY_STRING;
	}

	/**
	 * Returns the label for the specified resource or the empty string, never <code>null</code>
	 *
	 * @param selection the current {@link IStructuredSelection}
	 * @param resource the backing {@link IResource} for the selection
	 * @param shortcuts the list of {@link ILaunchShortcut}s to consider
	 * @param group the {@link ILaunchGroup} to launch using
	 * @return the label for the resource or the empty string, never <code>null</code>
	 */
	protected String getLabel(IStructuredSelection selection, IResource resource, List<LaunchShortcutExtension> shortcuts, ILaunchGroup group) {
		List<LaunchShortcutExtension> sc = pruneShortcuts(shortcuts, resource, group.getMode());
		LaunchConfigurationManager lcm = DebugUIPlugin.getDefault().getLaunchConfigurationManager();
		//see if the context is a shared configuration
		ILaunchConfiguration config = lcm.isSharedConfig(resource);
		if(config != null) {
			return appendLaunched(config);
		}
		List<ILaunchConfiguration> configs = getParticipatingLaunchConfigurations(selection, resource, sc, group.getMode());
		int csize = configs.size();
		if(csize == 1) {
			return appendLaunched(configs.get(0));
		}
		else if(csize > 1) {
			config = lcm.getMRUConfiguration(configs, group, resource);
			if(config != null) {
				return appendLaunched(config);
			}
			else {
				return ContextMessages.ContextRunner_14;
			}
		}
		else {
			List<LaunchShortcutExtension> exts = fExtCache.get(resource);
			if(exts == null && resource != null) {
				fExtCache.put(resource, sc);
			}
			int esize = sc.size();
			if(esize == 0) {
				if(resource != null && shouldCheckParent()) {
					IProject project = resource.getProject();
					if(project != null && !project.equals(resource)) {
						return getLabel(selection, project, sc, group);
					}
				}
				else if(shouldLaunchLast() || resource == null) {
					return getlastLaunchedLabel(group);
				}
				else {
					return ContextMessages.ContextRunner_15;
				}
			}
			if(esize == 1) {
				if(resource != null) {
					return resource.getName();
				}
				else {
					return MessageFormat.format(ContextMessages.LaunchingResourceManager_1, new Object[] { sc.get(0).getLabel() });
				}
			}
			else {
				return ContextMessages.ContextRunner_14;
			}
		}
	}

	/**
	 * Prunes the original listing of shortcuts
	 * @param shortcuts the original listing of <code>LaunchShortcutExtension</code>s
	 * @param resource the derived resource
	 * @param mode the mode we are wanting to launch in
	 * @return the list of {@link ILaunchShortcut}s to consider
	 *
	 * @since 3.4
	 */
	protected List<LaunchShortcutExtension> pruneShortcuts(List<LaunchShortcutExtension> shortcuts, IResource resource, String mode) {
		List<LaunchShortcutExtension> list = new ArrayList<>(shortcuts);
		if(resource == null) {
			LaunchShortcutExtension ext = null;
			for (ListIterator<LaunchShortcutExtension> iter = list.listIterator(); iter.hasNext();) {
				ext = iter.next();
				if(!ext.isParticipant()) {
					iter.remove();
				}
			}
		}
		else {
			list = getShortcutsForSelection(new StructuredSelection(resource), mode);
		}
		return list;
	}

	/**
	 * Computes the current resources context, given all of the launch shortcut participants
	 * and the current selection
	 * @param shortcuts the list of {@link ILaunchShortcut} to ask for mapped resources
	 * @param selection the current workbench {@link IStructuredSelection}
	 * @return The set of resources who care about this launch
	 *
	 * @since 3.4
	 */
	public IResource getLaunchableResource(List<LaunchShortcutExtension> shortcuts, IStructuredSelection selection) {
		if(selection != null && !selection.isEmpty()) {
			ArrayList<IResource> resources = new ArrayList<>();
			IResource resource = null;
			Object o = selection.getFirstElement();
			for (LaunchShortcutExtension ext : shortcuts) {
				if(o instanceof IEditorPart) {
					resource = ext.getLaunchableResource((IEditorPart) o);
				}
				else {
					resource = ext.getLaunchableResource(selection);
				}
				if(resource != null && !resources.contains(resource)) {
					resources.add(resource);
					resource = null;
				}
			}
			if(resources.size() > 0) {
				return resources.get(0);
			}
		}
		return null;
	}

	/**
	 * Returns the launch shortcuts that apply to the current <code>IStructuredSelection</code>
	 * @param selection the current selection
	 * @param mode the mode
	 * @return the list of shortcuts that apply to the given selection and mode or an empty listing, never <code>null</code>
	 *
	 * @since 3.4
	 */
	public List<LaunchShortcutExtension> getShortcutsForSelection(IStructuredSelection selection, String mode) {
		ArrayList<LaunchShortcutExtension> list = new ArrayList<>();
		List<LaunchShortcutExtension> sc = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchShortcuts();
		List<IEditorInput> ctxt = new ArrayList<>();
		// work around to bug in Structured Selection that returns actual underlying array in selection
		// @see bug 211646
		ctxt.addAll(selection.toList());
		Object o = selection.getFirstElement();
		if(o instanceof IEditorPart) {
			ctxt.set(0, ((IEditorPart)o).getEditorInput());
		}
		IEvaluationContext context = DebugUIPlugin.createEvaluationContext(ctxt);
		context.addVariable("selection", ctxt); //$NON-NLS-1$
		for (LaunchShortcutExtension ext : sc) {
			try {
				if(ext.evalEnablementExpression(context, ext.getContextualLaunchEnablementExpression()) &&
						ext.getModes().contains(mode) && !WorkbenchActivityHelper.filterItem(ext)) {
					if(!list.contains(ext)) {
						list.add(ext);
					}
				}
			}
			catch(CoreException ce) {}
		}
		return list;
	}

	/**
	 * Returns a listing of all launch configurations that want to participate in the contextual
	 * launch of the specified resource or specified selection
	 * @param resource the underlying resource
	 * @param selection the current selection in the workbench
	 * @param shortcuts the listing of shortcut extensions that apply to the current context
	 * @param mode the mode
	 * @return a listing of all launch configurations wanting to participate in the current launching
	 *
	 * @since 3.4
	 */
	public List<ILaunchConfiguration> getParticipatingLaunchConfigurations(IStructuredSelection selection, IResource resource, List<LaunchShortcutExtension> shortcuts, String mode) {
		List<ILaunchConfiguration> configs = new ArrayList<>();
		int voteDefault = 0;
		if(selection != null) {
			Object o = selection.getFirstElement();
			LaunchShortcutExtension ext = null;
			ILaunchConfiguration[] cfgs = null;
			for(int i = 0; i < shortcuts.size(); i++) {
				ext = shortcuts.get(i);
				if(o instanceof IEditorPart) {
					cfgs = ext.getLaunchConfigurations((IEditorPart)o);
				}
				else {
					 cfgs = ext.getLaunchConfigurations(selection);
				}
				if (cfgs == null) {
					Set<String> types = ext.getAssociatedConfigurationTypes();
					addAllToList(configs, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getApplicableLaunchConfigurations(types.toArray(new String[types.size()]), resource));
					voteDefault++;
				} else {
					if(cfgs.length > 0) {
						for(int j = 0; j < cfgs.length; j++) {
							configs.add(cfgs[j]);
						}
					}
				}
			}
		}
		if (voteDefault == shortcuts.size()) {
			// consider default configurations if no configurations were contributed
			addAllToList(configs, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getApplicableLaunchConfigurations(null, resource));
		}
		Iterator<ILaunchConfiguration> iterator = configs.iterator();
		while (iterator.hasNext()) {
			ILaunchConfiguration config = iterator.next();
			try {
				Set<String> modes = config.getModes();
				modes.add(mode);
				if (!config.getType().supportsModeCombination(modes)) {
					iterator.remove();
				}
			}
			catch (CoreException e) {}
		}
		return configs;
	}

	/**
	 * Adds all of the items in the given object array to the given collection.
	 * Does nothing if either the collection or array is <code>null</code>.
	 * @param list the {@link List} to append to
	 * @param values the array of {@link Object}s to add to the list
	 */
	private void addAllToList(List<ILaunchConfiguration> list, ILaunchConfiguration[] configs) {
		if (list == null || configs == null) {
			return;
		}
		for (int i = 0; i < configs.length; i++) {
			if (!list.contains(configs[i])) {
				list.add(configs[i]);
			}
		}
	}

	/**
	 * Starts up the manager
	 */
	public void startup() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		if(workbench != null) {
			workbench.addWindowListener(this);
			// initialize for already open windows
			IWorkbenchWindow[] workbenchWindows = workbench.getWorkbenchWindows();
			for (int i = 0; i < workbenchWindows.length; i++) {
				if (workbenchWindows[i].getSelectionService() != null) {
					windowOpened(workbenchWindows[i]);
				}
			}
		}
		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		DebugUIPlugin.getDefault().getLaunchConfigurationManager().addLaunchHistoryListener(this);
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
	}

	/**
	 * Shutdown and clean up the manager
	 */
	public void shutdown() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		if(workbench != null) {
			workbench.removeWindowListener(this);
		}
		DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		DebugUIPlugin.getDefault().getLaunchConfigurationManager().removeLaunchHistoryListener(this);
		DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
		for (IWorkbenchWindow window : fWindows) {
			window.getSelectionService().removeSelectionListener(this);
		}
		// set fUpdateLabel to false so that mouse track listener will do nothing if called
		// before the asynchronous execution disposes them
		fUpdateLabel = false;
		for (Entry<IWorkbenchWindow, ToolBar> entry : fToolbars.entrySet()) {
			final ToolBar bar = entry.getValue();
			if(bar != null && !bar.isDisposed()) {
				final MouseTrackAdapter listener = fMouseListener;
				DebugUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
					@Override
					public void run() {
						bar.removeMouseTrackListener(listener);
					}
				});

			}
		}
		fWindows.clear();
		fToolbars.clear();
		fLabelListeners.clear();
		fCurrentLabels.clear();
	}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowActivated(IWorkbenchWindow window) {
		if(!fToolbars.containsKey(window)) {
			addMouseListener(window);
		}
	}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowClosed(IWorkbenchWindow window) {
		ToolBar bar = fToolbars.remove(window);
		if(bar != null && !bar.isDisposed()) {
			bar.removeMouseTrackListener(fMouseListener);
		}
		if(fWindows.remove(window)) {
			window.getSelectionService().removeSelectionListener(this);
		}
	}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowDeactivated(IWorkbenchWindow window) {}

	/**
	 * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
	 */
	@Override
	public void windowOpened(IWorkbenchWindow window) {
		if(fWindows.add(window)) {
			window.getSelectionService().addSelectionListener(this);
		}
	}

	/**
	 * Adds a mouse listener to the launch toolbar
	 *
	 * @param window the {@link IWorkbenchWindow} to work with
	 */
	private void addMouseListener(IWorkbenchWindow window) {
		ICoolBarManager cmgr = ((WorkbenchWindow)window).getCoolBarManager2();
		if(cmgr != null) {
			IContributionItem item = cmgr.find("org.eclipse.debug.ui.launchActionSet"); //$NON-NLS-1$
			if(item instanceof ToolBarContributionItem) {
				ToolBarManager tmgr = (ToolBarManager) ((ToolBarContributionItem)item).getToolBarManager();
				ToolBar bar = tmgr.getControl();
				if(bar != null && !bar.isDisposed()) {
					bar.addMouseTrackListener(fMouseListener);
					fToolbars.put(window, bar);
				}
			}
		}
	}

	/**
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		if(event.getProperty().equals(IInternalDebugUIConstants.PREF_USE_CONTEXTUAL_LAUNCH) ||
				event.getProperty().equals(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE)) {
			if(isContextLaunchEnabled()) {
				windowActivated(DebugUIPlugin.getActiveWorkbenchWindow());
			}
			fUpdateLabel = true;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	@Override
	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
		if(isContextLaunchEnabled()) {
			fUpdateLabel = true;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.ILaunchHistoryChangedListener#launchHistoryChanged()
	 */
	@Override
	public void launchHistoryChanged() {
		//this always must be set to true, because as the history is loaded these events are fired, and we need to
		//update on workspace load.
		fUpdateLabel = true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchesListener2#launchesTerminated(org.eclipse.debug.core.ILaunch[])
	 */
	@Override
	public void launchesTerminated(ILaunch[] launches) {
		fUpdateLabel = true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(org.eclipse.debug.core.ILaunch[])
	 */
	@Override
	public void launchesAdded(ILaunch[] launches) {
		fUpdateLabel = true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(org.eclipse.debug.core.ILaunch[])
	 */
	@Override
	public void launchesChanged(ILaunch[] launches) {}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(org.eclipse.debug.core.ILaunch[])
	 */
	@Override
	public void launchesRemoved(ILaunch[] launches) {
		//we want to ensure that even if a launch is removed from the debug view
		//when it is not terminated we update the label just in case.
		//bug 195232
		for(int i = 0; i < launches.length; i++) {
			if(!launches[i].isTerminated()) {
				fUpdateLabel = true;
				return;
			}
		}
	}
}
