/*******************************************************************************
 * Copyright (c) 2000, 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.ui;


import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.commands.operations.ObjectUndoContext;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
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.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchDelegate;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.internal.core.IConfigurationElementConstants;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DefaultLabelProvider;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.LazyModelPresentation;
import org.eclipse.debug.internal.ui.actions.ActionMessages;
import org.eclipse.debug.internal.ui.actions.ToggleBreakpointsTargetManager;
import org.eclipse.debug.internal.ui.contexts.DebugContextManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationDialog;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPropertiesDialog;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchGroupExtension;
import org.eclipse.debug.internal.ui.memory.MemoryRenderingManager;
import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupFacility;
import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupUIUtils;
import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetManager;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextManager;
import org.eclipse.debug.ui.contexts.IDebugContextService;
import org.eclipse.debug.ui.memory.IMemoryRenderingManager;
import org.eclipse.debug.ui.sourcelookup.ISourceContainerBrowser;
import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.ide.undo.DeleteMarkersOperation;
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;


/**
 * This class provides utilities for clients of the debug UI.
 * <p>
 * Images retrieved from this facility should not be disposed.
 * The images will be disposed when this plug-in is shutdown.
 * </p>
 * <p>
 * Note: all methods in this class are expected to be called 
 * on the Display thread unless otherwise noted.
 * </p>
 * @noinstantiate This class is not intended to be instantiated by clients.
 * @noextend This class is not intended to be subclassed by clients.
 */
public class DebugUITools {
	
	/**
	 * The undo context for breakpoints.
	 * 
	 * @since 3.7
	 */
	private static ObjectUndoContext fgBreakpointsUndoContext;

	/**
	 * Returns the shared image managed under the given key, or <code>null</code>
	 * if none.
	 * <p>
	 * Note that clients <b>MUST NOT</b> dispose the image returned by this method.
	 * </p>
	 * <p>
	 * See <code>IDebugUIConstants</code> for available images.
	 * </p>
	 *
	 * @param key the image key
	 * @return the image, or <code>null</code> if none
	 * @see IDebugUIConstants
	 */
	public static Image getImage(String key) {
		return DebugPluginImages.getImage(key);
	}
	
	/**
	 * Returns the shared image descriptor managed under the given key, or
	 * <code>null</code> if none.
	 * <p>
	 * See <code>IDebugUIConstants</code> for available image descriptors.
	 * </p>
	 *
	 * @param key the image descriptor key
	 * @return the image descriptor, or <code>null</code> if none
	 * @see IDebugUIConstants
	 */
	public static ImageDescriptor getImageDescriptor(String key) {
		return DebugPluginImages.getImageDescriptor(key);
	}
		
	/**
	 * Returns the default image descriptor for the given element.
	 * 
	 * @param element the element
	 * @return the image descriptor or <code>null</code> if none
	 */
	public static ImageDescriptor getDefaultImageDescriptor(Object element) {
		String imageKey= getDefaultImageKey(element);
		if (imageKey == null) {
			return null;
		}
		return DebugPluginImages.getImageDescriptor(imageKey);
	}
	
	private static String getDefaultImageKey(Object element) {
		return ((DefaultLabelProvider)DebugUIPlugin.getDefaultLabelProvider()).getImageKey(element);
	}
	
	/**
	 * Returns the preference store for the debug UI plug-in.
	 *
	 * @return preference store
	 */
	public static IPreferenceStore getPreferenceStore() {
		return DebugUIPlugin.getDefault().getPreferenceStore();
	}
	
	/**
	 * Returns a new debug model presentation that delegates to
	 * appropriate debug models.
	 * <p>
	 * It is the client's responsibility dispose the presentation.
	 * </p>
	 * 
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
	 * @return a debug model presentation
	 * @since 2.0
	 */
	public static IDebugModelPresentation newDebugModelPresentation() {
		return new DelegatingModelPresentation();
	}
	
	/**
	 * Returns a new debug model presentation for specified
	 * debug model, or <code>null</code> if a presentation does
	 * not exist.
	 * <p>
	 * It is the client's responsibility dispose the presentation.
	 * </p>
	 * 
	 * @param identifier debug model identifier
	 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
	 * @return a debug model presentation, or <code>null</code>
	 * @since 2.0
	 */
	public static IDebugModelPresentation newDebugModelPresentation(String identifier) {
		IExtensionPoint point= Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.ID_DEBUG_MODEL_PRESENTATION);
		if (point != null) {
			IExtension[] extensions= point.getExtensions();
			for (int i= 0; i < extensions.length; i++) {
				IExtension extension= extensions[i];
				IConfigurationElement[] configElements= extension.getConfigurationElements();
				for (int j= 0; j < configElements.length; j++) {
					IConfigurationElement elt= configElements[j];
					String id= elt.getAttribute("id"); //$NON-NLS-1$
					if (id != null && id.equals(identifier)) {
						return new LazyModelPresentation(elt);
					}
				}
			}
		}
		return null;
	}	
	
	/**
 	 * Returns the element of the currently selected context in the 
	 * active workbench window. Returns <code>null</code> if there is no 
	 * current debug context.
	 * <p>
	 * This method used to return <code>null</code> when called from a non-UI thread,
	 * but since 3.1, this methods also works when called from a non-UI thread.
	 * </p>
	 * @return the currently selected debug context, or <code>null</code>
	 * @since 2.0
	 */
	public static IAdaptable getDebugContext() {
	    IWorkbenchWindow activeWindow = SelectedResourceManager.getDefault().getActiveWindow();
	    if (activeWindow != null) {
	    	ISelection activeContext = DebugUITools.getDebugContextManager().getContextService(activeWindow).getActiveContext();
	    	return getDebugContextElementForSelection(activeContext);
	    }
	    return null;
	}

    /**
     * Returns the currently selected context in the given part or part's  
     * workbench window. Returns <code>null</code> if there is no current 
     * debug context.
     * @param part workbench part where the active context is to be evaluated
     * @return the currently selected debug context in the given workbench part, 
     * or <code>null</code>
     * @since 3.8
     * @see IDebugContextService#getActiveContext(String)
     * @see IDebugContextService#getActiveContext(String, String)
     */
    public static ISelection getDebugContextForPart(IWorkbenchPart part) {
        IWorkbenchPartSite site = part.getSite();
        IWorkbenchWindow partWindow = site.getWorkbenchWindow();
        if (partWindow != null) {
            IDebugContextService contextService = DebugUITools.getDebugContextManager().getContextService(partWindow);
            if (site instanceof IViewSite) {
                return contextService.getActiveContext(site.getId(), ((IViewSite)site).getSecondaryId());
            } else {
                return contextService.getActiveContext(site.getId());
            }
        }
        return null;
    }
	
	/**
	 * Return the undo context that should be used for operations involving breakpoints.
	 * 
	 * @return the undo context for breakpoints
	 * @since 3.7
	 */
	public static synchronized IUndoContext getBreakpointsUndoContext() {
		if (fgBreakpointsUndoContext == null) {
			fgBreakpointsUndoContext= new ObjectUndoContext(new Object(), "Breakpoints Context"); //$NON-NLS-1$
			fgBreakpointsUndoContext.addMatch(WorkspaceUndoUtil.getWorkspaceUndoContext());
		}
		return fgBreakpointsUndoContext;
	}

	/**
	 * Deletes the given breakpoints using the operation history, which allows to undo the deletion.
	 * 
	 * @param breakpoints the breakpoints to delete
	 * @param shell the shell used for potential user interactions, or <code>null</code> if unknown
	 * @param progressMonitor the progress monitor
	 * @throws CoreException if the deletion fails
	 * @since 3.7
	 */
	public static void deleteBreakpoints(IBreakpoint[] breakpoints, final Shell shell, IProgressMonitor progressMonitor) throws CoreException {
		IMarker[] markers= new IMarker[breakpoints.length];
		int markerCount;
		for (markerCount= 0; markerCount < breakpoints.length; markerCount++) {
			if (!breakpoints[markerCount].isRegistered()) {
				break;
			}
			markers[markerCount]= breakpoints[markerCount].getMarker();
			if (markers[markerCount] == null) {
				break;
			}
		}

		// We only offer undo support if all breakpoints are registered and have associated markers
		boolean allowUndo= markerCount == breakpoints.length;

		DebugPlugin.getDefault().getBreakpointManager().removeBreakpoints(breakpoints, !allowUndo);

		if (allowUndo) {

			for (int i= 0; i < markers.length; i++) {
				markers[i].setAttribute(DebugPlugin.ATTR_BREAKPOINT_IS_DELETED, true);
			}

			IAdaptable context= null;
			if (shell != null) {
				context= new IAdaptable() {
					@SuppressWarnings("unchecked")
					@Override
					public <T> T getAdapter(Class<T> adapter) {
						if (adapter == Shell.class) {
							return (T) shell;
						}
						return null;
					}
				};
			}

			String operationName= markers.length == 1 ? ActionMessages.DeleteBreakpointOperationName : ActionMessages.DeleteBreakpointsOperationName;
			IUndoableOperation deleteMarkerOperation= new DeleteMarkersOperation(markers, operationName);
			deleteMarkerOperation.removeContext(WorkspaceUndoUtil.getWorkspaceUndoContext());
			deleteMarkerOperation.addContext(DebugUITools.getBreakpointsUndoContext());
			IOperationHistory operationHistory= PlatformUI.getWorkbench().getOperationSupport().getOperationHistory();
			try {
				operationHistory.execute(deleteMarkerOperation, progressMonitor, context);
			} catch (ExecutionException e) {
				throw new CoreException(DebugUIPlugin.newErrorStatus("Exception while deleting breakpoint markers", e)); //$NON-NLS-1$
			}
		}
	}

    /**
     * Returns the currently active context for the given workbench part. Returns <code>null</code>
     * if there is no current debug context.</p>
     * 
     * @param site the part's site where to look up the active context
     * @return the currently active debug context in the given part, or <code>null</code>
     * @since 3.7
     */
    public static IAdaptable getPartDebugContext(IWorkbenchPartSite site) {
        IDebugContextService service = DebugUITools.getDebugContextManager().getContextService(site.getWorkbenchWindow());
        String id = null;
        String secondaryId = null;
        id = site.getId();
        if (site instanceof IViewSite) {
            secondaryId = ((IViewSite)site).getSecondaryId();
        }
        ISelection activeContext = service.getActiveContext(id, secondaryId); 
        return getDebugContextElementForSelection(activeContext);
    }

    /**
     * Adds the given debug context listener as a listener to the debug context changed events, in
     * the context of the given workbench part.
     * <p>
     * This method is a utility method which ultimately calls
     * {@link IDebugContextService#addDebugContextListener(IDebugContextListener, String, String)}
     * using the part id parameters extracted from the given part parameter.
     * </p>
     * 
     * @param site the part's site to get the part ID and part secondary ID from
     * @param listener Debug context listener to add
     * 
     * @see IDebugContextService#addDebugContextListener(IDebugContextListener, String, String)
     * @see IDebugContextManager#addDebugContextListener(IDebugContextListener)
     * @since 3.7
     */
    public static void addPartDebugContextListener(IWorkbenchPartSite site, IDebugContextListener listener) {
        IDebugContextService service = DebugUITools.getDebugContextManager().getContextService(site.getWorkbenchWindow());
        String id = site.getId();
        String secondaryId = null;
        if (site instanceof IViewSite) {
            secondaryId = ((IViewSite)site).getSecondaryId();
        }
        service.addDebugContextListener(listener, id, secondaryId);
    }

    /**
     * Removes the given debug context listener as a listener to the debug context changed events,
     * in the context of the given workbench part.
     * <p>
     * This method is a utility method which ultimately calls
     * {@link IDebugContextService#removeDebugContextListener(IDebugContextListener, String, String)}
     * using the part id parameters extracted from the given part parameter.
     * </p>
     * 
     * @param site the part's site to get the part ID and part secondary ID from
     * @param listener Debug context listener to remove
     * 
     * @see IDebugContextService#removeDebugContextListener(IDebugContextListener, String, String)
     * @see IDebugContextManager#removeDebugContextListener(IDebugContextListener)
     * @since 3.7
     */
    public static void removePartDebugContextListener(IWorkbenchPartSite site, IDebugContextListener listener) {
        IDebugContextService service = DebugUITools.getDebugContextManager().getContextService(site.getWorkbenchWindow());
        String id = site.getId();
        String secondaryId = null;
        if (site instanceof IViewSite) {
            secondaryId = ((IViewSite)site).getSecondaryId();
        }
        service.removeDebugContextListener(listener, id, secondaryId);
    }
    
    /**
	 * Extracts the first element from the given selection and casts it to IAdaptable.
	 * 
	 * @param activeContext the selection
	 * @return an adaptable
	 */
    private static IAdaptable getDebugContextElementForSelection(ISelection activeContext) {
        if (activeContext instanceof IStructuredSelection) {
            IStructuredSelection selection = (IStructuredSelection) activeContext;
            if (!selection.isEmpty()) {
                Object firstElement = selection.getFirstElement();
                if (firstElement instanceof IAdaptable) {
                    return (IAdaptable) firstElement;
                }
            }
        }
        return null;
    }
    
	/**
	 * Returns the currently selected resource in the active workbench window,
	 * or <code>null</code> if none. If an editor is active, the resource adapter
	 * associated with the editor is returned, if any.
	 * 
	 * @return selected resource or <code>null</code>
	 * @since 3.0
	 */
	public static IResource getSelectedResource() {
		return SelectedResourceManager.getDefault().getSelectedResource();
	}
			
	/**
	 * Returns the process associated with the current debug context.
	 * If there is no debug context currently, the most recently
	 * launched process is returned. If there is no current process
	 * <code>null</code> is returned.
	 * 
	 * @return the current process, or <code>null</code>
	 * @since 2.0
	 */
	public static IProcess getCurrentProcess() {
		IAdaptable context = getDebugContext();
		if (context == null) {
			ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
			if (launches.length > 0) {
				context = launches[launches.length - 1];
			}
		}
        
		if (context instanceof IDebugElement) {
			return ((IDebugElement)context).getDebugTarget().getProcess();
		}
		
        if (context instanceof IProcess) {
			return (IProcess)context;
		}
		
        if (context instanceof ILaunch) {
			ILaunch launch= (ILaunch)context;
			IDebugTarget target= launch.getDebugTarget();
			if (target != null) {
				IProcess process = target.getProcess();
				if (process != null) {
					return process;
				}
			}
			IProcess[] ps = launch.getProcesses();
			if (ps.length > 0) {
				return ps[ps.length - 1];
			}
		}
        
        if (context != null) {
            return context.getAdapter(IProcess.class);
        }
        
		return null;
	}

	/**
	 * Open the launch configuration dialog with the specified initial selection.
	 * The selection may be <code>null</code>, or contain any mix of 
	 * <code>ILaunchConfiguration</code> or <code>ILaunchConfigurationType</code>
	 * elements.
	 * <p>
	 * Before opening a new dialog, this method checks if there is an existing open
	 * launch configuration dialog.  If there is, this dialog is used with the
	 * specified selection.  If there is no existing dialog, a new one is created.
	 * </p>
	 * <p>
	 * Note that if an existing dialog is reused, the <code>mode</code> argument is ignored
	 * and the existing dialog keeps its original mode.
	 * </p>
	 * 
	 * @param shell the parent shell for the launch configuration dialog
	 * @param selection the initial selection for the dialog
	 * @param mode the mode (run or debug) in which to open the launch configuration dialog.
	 *  This should be one of the constants defined in <code>ILaunchManager</code>.
	 * @return the return code from opening the launch configuration dialog -
	 *  one  of <code>Window.OK</code> or <code>Window.CANCEL</code>. <code>Window.CANCEL</code>
	 *  is returned if an invalid launch group identifier is provided.
	 * @see ILaunchGroup
	 * @since 2.0
	 * @deprecated use openLaunchConfigurationDialogOnGroup(Shell, IStructuredSelection, String)
	 *  to specify the launch group that the dialog should be opened on. This method will open
	 *  on the launch group with the specified mode and a <code>null</code> category 
	 */
	@Deprecated
	public static int openLaunchConfigurationDialog(Shell shell, IStructuredSelection selection, String mode) {
		ILaunchGroup[] groups = getLaunchGroups();
		for (int i = 0; i < groups.length; i++) {
			ILaunchGroup group = groups[i];
			if (group.getMode().equals(mode) && group.getCategory() == null) {
				return openLaunchConfigurationDialogOnGroup(shell, selection, group.getIdentifier());
			}
		}
		return Window.CANCEL;
	}
	
	/**
	 * Open the launch configuration dialog with the specified initial selection.
	 * The selection may be <code>null</code>, or contain any mix of 
	 * <code>ILaunchConfiguration</code> or <code>ILaunchConfigurationType</code>
	 * elements.
	 * <p>
	 * Before opening a new dialog, this method checks if there is an existing open
	 * launch configuration dialog.  If there is, this dialog is used with the
	 * specified selection.  If there is no existing dialog, a new one is created.
	 * </p>
	 * <p>
	 * Note that if an existing dialog is reused, the <code>mode</code> argument is ignored
	 * and the existing dialog keeps its original mode.
	 * </p>
	 * 
	 * @param shell the parent shell for the launch configuration dialog
	 * @param selection the initial selection for the dialog
	 * @param groupIdentifier the identifier of the launch group to display (corresponds to
	 * the identifier of a launch group extension)
	 * @return The return code from opening the launch configuration dialog -
	 *  one  of <code>Window.OK</code> or <code>Window.CANCEL</code>. <code>Window.CANCEL</code>
	 *  is returned if an invalid launch group identifier is provided.
	 * @see ILaunchGroup
	 * @since 2.1
	 */
	public static int openLaunchConfigurationDialogOnGroup(Shell shell, IStructuredSelection selection, String groupIdentifier) {
		return openLaunchConfigurationDialogOnGroup(shell, selection, groupIdentifier, null);
	}
	
	/**
	 * Open the launch configuration dialog with the specified initial selection.
	 * The selection may be <code>null</code>, or contain any mix of 
	 * <code>ILaunchConfiguration</code> or <code>ILaunchConfigurationType</code>
	 * elements.
	 * <p>
	 * Before opening a new dialog, this method checks if there is an existing open
	 * launch configuration dialog.  If there is, this dialog is used with the
	 * specified selection.  If there is no existing dialog, a new one is created.
	 * </p>
	 * <p>
	 * Note that if an existing dialog is reused, the <code>mode</code> argument is ignored
	 * and the existing dialog keeps its original mode.
	 * </p>
	 * <p>
	 * If a status is specified, a status handler is consulted to handle the
	 * status. The status handler is passed the instance of the launch
	 * configuration dialog that is opened. This gives the status handler an
	 * opportunity to perform error handling/initialization as required.
	 * </p>
	 * @param shell the parent shell for the launch configuration dialog
	 * @param selection the initial selection for the dialog
	 * @param groupIdentifier the identifier of the launch group to display (corresponds to
	 * the identifier of a launch group extension)
	 * @param status the status to display in the dialog, or <code>null</code>
	 * if none
	 * @return the return code from opening the launch configuration dialog -
	 *  one  of <code>Window.OK</code> or <code>Window.CANCEL</code>. <code>Window.CANCEL</code>
	 *  is returned if an invalid launch group identifier is provided.
	 * @see org.eclipse.debug.core.IStatusHandler
	 * @see ILaunchGroup
	 * @since 2.1
	 */
	public static int openLaunchConfigurationDialogOnGroup(final Shell shell, final IStructuredSelection selection, final String groupIdentifier, final IStatus status) {
		final int[] result = new int[1];
		Runnable r = new Runnable() {
			/**
			 * @see java.lang.Runnable#run()
			 */
			@Override
			public void run() {
				LaunchConfigurationsDialog dialog = (LaunchConfigurationsDialog) LaunchConfigurationsDialog.getCurrentlyVisibleLaunchConfigurationDialog();
				if (dialog != null) {
					dialog.setInitialSelection(selection);
					dialog.doInitialTreeSelection();
					if (status != null) {
						dialog.handleStatus(status); 
					}
					result[0] = Window.OK;
				} else {
					LaunchGroupExtension ext = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier);
					if(ext != null) {
						dialog = new LaunchConfigurationsDialog(shell, ext);
						dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION);
						dialog.setInitialSelection(selection);
						dialog.setInitialStatus(status);
						result[0] = dialog.open();
					}
					else {
						result[0] = Window.CANCEL;
					}
				}
			}
		};
		BusyIndicator.showWhile(DebugUIPlugin.getStandardDisplay(), r);
		return result[0];
	}
		
	/**
	 * Open the launch configuration properties dialog on the specified launch
	 * configuration.
	 *
	 * @param shell the parent shell for the launch configuration dialog
	 * @param configuration the configuration to display
	 * @param groupIdentifier group identifier of the launch group the launch configuration
	 * belongs to
	 * @return the return code from opening the launch configuration dialog -
	 *  one  of <code>Window.OK</code> or <code>Window.CANCEL</code>. <code>Window.CANCEL</code>
	 *  is returned if an invalid launch group identifier is provided.
	 * @see ILaunchGroup
	 * @since 2.1
	 */
	public static int openLaunchConfigurationPropertiesDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier) {
		return openLaunchConfigurationPropertiesDialog(shell, configuration, groupIdentifier, null);
	}
	
	/**
	 * Open the launch configuration properties dialog on the specified launch
	 * configuration.
	 *
	 * @param shell the parent shell for the launch configuration dialog
	 * @param configuration the configuration to display
	 * @param groupIdentifier group identifier of the launch group the launch configuration
	 * belongs to
	 * @param status the status to display, or <code>null</code> if none
	 * @return the return code from opening the launch configuration dialog -
	 *  one  of <code>Window.OK</code> or <code>Window.CANCEL</code>. <code>Window.CANCEL</code>
	 *  is returned if an invalid launch group identifier is provided.
	 * @see ILaunchGroup
	 * @since 3.0
	 */
	public static int openLaunchConfigurationPropertiesDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier, IStatus status) {
		LaunchGroupExtension group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier);
		if (group != null) {
			LaunchConfigurationPropertiesDialog dialog = new LaunchConfigurationPropertiesDialog(shell, configuration, group);
			dialog.setInitialStatus(status);
			return dialog.open();
		} 
		
		return Window.CANCEL;
	}
	
	/**
     * Open the launch configuration dialog on the specified launch
     * configuration. The dialog displays the tabs for a single configuration
     * only (a tree of launch configuration is not displayed), and provides a
     * launch (run or debug) button.
     * <p>
     * If a status is specified, a status handler is consulted to handle the
     * status. The status handler is passed the instance of the launch
     * configuration dialog that is opened. This gives the status handler an
     * opportunity to perform error handling/initialization as required.
     * </p>
     * @param shell the parent shell for the launch configuration dialog
     * @param configuration the configuration to display
     * @param groupIdentifier group identifier of the launch group the launch configuration
     * belongs to
     * @param status the status to display, or <code>null</code> if none 
     * @return the return code from opening the launch configuration dialog -
     *  one  of <code>Window.OK</code> or <code>Window.CANCEL</code>. <code>Window.CANCEL</code>
	 *  is returned if an invalid launch group identifier is provided.
	 * @see ILaunchGroup 
     * @since 2.1
     */
    public static int openLaunchConfigurationDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier, IStatus status) {
    	LaunchGroupExtension group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier);
    	if (group != null) {
    		LaunchConfigurationDialog dialog = new LaunchConfigurationDialog(shell, configuration, group);
    		dialog.setInitialStatus(status);
    		return dialog.open();
    	} 
    		
    	return Window.CANCEL;
    }
    
	/**
	 * Saves all dirty editors and builds the workspace according to current
	 * preference settings, and returns whether a launch should proceed.
	 * <p>
	 * The following preferences affect whether dirty editors are saved,
	 * and/or if the user is prompted to save dirty editors:<ul>
	 * <li>PREF_NEVER_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH</li>
	 * <li>PREF_PROMPT_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH</li>
	 * <li>PREF_AUTOSAVE_DIRTY_EDITORS_BEFORE_LAUNCH</li>
	 * </ul>
	 * The following preference affects whether a build is performed before
	 * launching (if required):<ul>
	 * <li>PREF_BUILD_BEFORE_LAUNCH</li>
	 * </ul>
	 * </p>
	 * 
	 * @return whether a launch should proceed
	 * @since 2.0
	 * @deprecated Saving has been moved to the launch delegate <code>LaunchConfigurationDelegate</code> to allow for scoped saving
	 * of resources that are only involved in the current launch, no longer the entire workspace
	 */
	@Deprecated
	public static boolean saveAndBuildBeforeLaunch() {
		return DebugUIPlugin.saveAndBuild();
	}
	
	/**
	 * Saves all dirty editors according to current
	 * preference settings, and returns whether a launch should proceed.
	 * <p>
	 * The following preferences affect whether dirty editors are saved,
	 * and/or if the user is prompted to save dirty editors:<ul>
	 * <li>PREF_NEVER_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH</li>
	 * <li>PREF_PROMPT_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH</li>
	 * <li>PREF_AUTOSAVE_DIRTY_EDITORS_BEFORE_LAUNCH</li>
	 * </ul>
	 * </p>
	 * 
	 * @return whether a launch should proceed
	 * @since 2.1
	 * @deprecated Saving has been moved to the launch delegate <code>LaunchConfigurationDelegate</code> to allow for scoped saving
	 * of resources that are only involved in the current launch, no longer the entire workspace
	 */
	@Deprecated
	public static boolean saveBeforeLaunch() {
		return DebugUIPlugin.preLaunchSave();
	}	
	
	/**
	 * Saves and builds the workspace according to current preference settings,
	 * and launches the given launch configuration in the specified mode. It
	 * terminates the current launch for the same configuration if it was
	 * specified via Preferences or toggled by Shift.
	 * <p>
	 * This method must be called in the UI thread.
	 * </p>
	 * 
	 * @param configuration the configuration to launch
	 * @param mode launch mode - run or debug
	 * @since 2.1
	 */
	public static void launch(final ILaunchConfiguration configuration, final String mode) {
		launch(configuration, mode, DebugUITools.findTogglelaunchForConfig(configuration));
	}

	private static HashMap<Object, Boolean> fgLaunchToggleTerminateMap = new HashMap<>();

	/**
	 * Stores the toggle data for launch in a Map to be used while launching to
	 * decide if previous launch for same configuration can be terminated.
	 * 
	 * @param data the editor or selected tree node
	 * @param isShift is Shift pressed (use <code>false</code> if no support for
	 *            Shift)
	 * @since 3.12
	 */
	public static void storeLaunchToggleTerminate(Object data, Boolean isShift) {
		synchronized (fgLaunchToggleTerminateMap) {
			fgLaunchToggleTerminateMap.put(data, isShift);
		}
	}

	/**
	 * @since 3.12
	 */
	private static boolean getAndRemoveLaunchToggleTerminate(Object data) {

		Boolean isShift;
		synchronized (fgLaunchToggleTerminateMap) {
			isShift = fgLaunchToggleTerminateMap.get(data);
		}
		if (isShift != null) {
			synchronized (fgLaunchToggleTerminateMap) {
				fgLaunchToggleTerminateMap.remove(data);
			}
			return isShift.booleanValue();
		}
		return Boolean.FALSE;
	}

	/**
	 * @since 3.12
	 */
	private static boolean findTogglelaunchForConfig(ILaunchConfiguration configuration) {
		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
		ILaunch[] launches = launchManager.getLaunches();
		for (ILaunch iLaunch : launches) {
			if (configuration.contentsEqual(iLaunch.getLaunchConfiguration())) {
				try {
					IResource[] configResource = iLaunch.getLaunchConfiguration().getMappedResources();
					if (configResource != null && configResource.length == 1) {
						for (Iterator<Object> iter = fgLaunchToggleTerminateMap.keySet().iterator(); iter.hasNext();) {
							Object key = iter.next();
							if (key instanceof IEditorPart) {
								IEditorInput input = ((IEditorPart) key).getEditorInput();
								if (input.getAdapter(IResource.class).equals(configResource[0])) {
									return getAndRemoveLaunchToggleTerminate(key);
								}
							} else if (key instanceof TreeSelection) {
								TreeSelection selection = (TreeSelection) key;
								TreePath[] treePath = selection.getPaths();
								if (treePath != null && treePath.length == 1) {
									Object lastSegmentObj = treePath[0].getLastSegment();
									IResource selectedResource = ((IAdaptable) lastSegmentObj).getAdapter(IResource.class);
									if (selectedResource!= null && selectedResource.equals(configResource[0])) {
										return getAndRemoveLaunchToggleTerminate(key);
									}
								}
							}
						}
					}

				} catch (CoreException e) {
					e.printStackTrace();
				}
			}
		}
		return false;

	}
	
	/**
	 * Saves and builds the workspace according to current preference settings,
	 * and launches the given launch configuration in the specified mode.
	 * <p>
	 * This method must be called in the UI thread.
	 * </p>
	 * 
	 * @param configuration the configuration to launch
	 * @param mode launch mode - run or debug
	 * @since 3.12
	 */
	public static void reLaunch(final ILaunchConfiguration configuration, final String mode) {
		boolean launchInBackground = true;
		try {
			launchInBackground = configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
		}
		if (launchInBackground) {
			DebugUIPlugin.launchInBackground(configuration, mode);
		} else {
			DebugUIPlugin.launchInForeground(configuration, mode);
		}

	}


	/**
	 * Saves and builds the workspace according to current preference settings,
	 * and launches the given launch configuration in the specified mode. It
	 * terminates the current launch for the same configuration if it was
	 * specified via Preferences or toggled by Shift
	 * <p>
	 * This method must be called in the UI thread.
	 * </p>
	 * 
	 * @param configuration the configuration to launch
	 * @param mode launch mode - run or debug
	 * @param isShift is Shift pressed (use <code>false</code> if no support for
	 *            Shift)
	 * @since 3.12
	 */
	public static void launch(final ILaunchConfiguration configuration, final String mode, boolean isShift) {
		if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_TERMINATE_AND_RELAUNCH_LAUNCH_ACTION) != isShift) {
			ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
			ILaunch[] launches = launchManager.getLaunches();
			for (ILaunch iLaunch : launches) {
				if (configuration.contentsEqual(iLaunch.getLaunchConfiguration())) {
					try {
						iLaunch.terminate();
					} catch (DebugException e) {
						DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), NLS.bind(ActionMessages.TerminateAndLaunchFailure, iLaunch.getLaunchConfiguration().getName()), e));
					}
				}
			}
		}
		boolean launchInBackground = true;
		try {
			launchInBackground = configuration.getAttribute(IDebugUIConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
		} catch (CoreException e) {
			DebugUIPlugin.log(e);
		}
		if (launchInBackground) {
			DebugUIPlugin.launchInBackground(configuration, mode);
		} else {
			DebugUIPlugin.launchInForeground(configuration, mode);
		}
	}

	
	/**
	 * Builds the workspace according to current preference settings, and launches
	 * the given configuration in the specified mode, returning the resulting launch
	 * object.
	 * <p>
	 * The following preference affects whether a build is performed before
	 * launching (if required):<ul>
	 * <li>PREF_BUILD_BEFORE_LAUNCH</li>
	 * </ul>
	 * </p>
	 * 
	 * @param configuration the configuration to launch
	 * @param mode the mode to launch in
	 * @param monitor progress monitor
	 * @return the resulting launch object
	 * @throws CoreException if building or launching fails
	 * @since 2.1
	 */
	public static ILaunch buildAndLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
		return DebugUIPlugin.buildAndLaunch(configuration, mode, monitor);
	}
	
	/**
	 * Returns the perspective to switch to when a configuration of the given type
	 * is launched in the given mode, or <code>null</code> if no switch should take
	 * place.
	 * 
	 * In 3.3 this method is equivalent to calling <code>getLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate)</code>,
	 * with the 'mode' parameter comprising a single element set and passing <code>null</code> as the launch delegate.
	 * 
	 * @param type launch configuration type
	 * @param mode launch mode identifier
	 * @return perspective identifier or <code>null</code>
	 * @since 3.0
	 */
	public static String getLaunchPerspective(ILaunchConfigurationType type, String mode) {
		return DebugUIPlugin.getDefault().getPerspectiveManager().getLaunchPerspective(type, mode);
	}
	
	/**
	 * Returns the perspective id to switch to when a configuration of the given type launched with the specified delegate
	 * is launched in the given mode set, or <code>null</code> if no switch should occurr.
	 * @param type the configuration type
	 * @param delegate the launch delegate
	 * @param modes the set of modes
	 * @return the perspective id or <code>null</code> if no switch should occur
	 * 
	 * @since 3.3
	 */
	public static String getLaunchPerspective(ILaunchConfigurationType type, ILaunchDelegate delegate, Set<String> modes) {
		return DebugUIPlugin.getDefault().getPerspectiveManager().getLaunchPerspective(type, modes, delegate);
	}
	
	/**
	 * Sets the perspective to switch to when a configuration of the given type
	 * is launched in the given mode. <code>PERSPECTIVE_NONE</code> indicates no
	 * perspective switch should take place. <code>PERSPECTIVE_DEFAULT</code> indicates
	 * a default perspective switch should take place, as defined by the associated
	 * launch tab group extension.
	 * 
	 * In 3.3 this method is equivalent to calling <code>setLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate, String perspectiveid)</code>, 
	 * with the parameter 'mode' used in the set modes, and null passed as the delegate
	 * 
	 * @param type launch configuration type
	 * @param mode launch mode identifier
	 * @param perspective identifier, <code>PERSPECTIVE_NONE</code>, or
	 *   <code>PERSPECTIVE_DEFAULT</code>
	 * @since 3.0
	 */
	public static void setLaunchPerspective(ILaunchConfigurationType type, String mode, String perspective) {
		DebugUIPlugin.getDefault().getPerspectiveManager().setLaunchPerspective(type, mode, perspective);
	}	
	
	/**
	 * Sets the perspective to switch to when a configuration of the specified type and launched using the 
	 * specified launch delegate is launched in the specified modeset. <code>PERSPECTIVE_NONE</code> indicates no
	 * perspective switch should take place.
	 * 
	 * Passing <code>null</code> for the launch delegate is quivalent to using the default perspective for the specified 
	 * type.
	 * @param type the configuration type
	 * @param delegate the launch delegate
	 * @param modes the set of modes
	 * @param perspectiveid identifier or <code>PERSPECTIVE_NONE</code>
	 * 
	 * @since 3.3
	 */
	public static void setLaunchPerspective(ILaunchConfigurationType type, ILaunchDelegate delegate, Set<String> modes, String perspectiveid) {
		DebugUIPlugin.getDefault().getPerspectiveManager().setLaunchPerspective(type, modes, delegate, perspectiveid);
	}
	
	/**
	 * Returns whether the given launch configuration is private. Generally,
	 * private launch configurations should not be displayed to the user. The
	 * private status of a launch configuration is determined by the
	 * <code>IDebugUIConstants.ATTR_PRIVATE</code> attribute.
	 * 
	 * @param configuration launch configuration
	 * @return whether the given launch configuration is private
	 * @since 3.0
	 */
	public static boolean isPrivate(ILaunchConfiguration configuration) {
		return !LaunchConfigurationManager.isVisible(configuration);
	}

	/**
	 * Sets whether step filters should be applied to step commands. This
	 * setting is a global option applied to all registered debug targets. 
	 * <p>
	 * Since 3.3, this is equivalent to calling <code>DebugPlugin.setUseStepFilters(boolean)</code>.
	 * </p>
	 * @param useStepFilters whether step filters should be applied to step
	 *  commands
	 * @since 3.0
	 * @see org.eclipse.debug.core.model.IStepFilters
	 */
	public static void setUseStepFilters(boolean useStepFilters) {
		DebugPlugin.setUseStepFilters(useStepFilters);
	}
		
	/**
	 * Returns whether step filters are applied to step commands.
	 * <p>
	 * Since 3.3, this is equivalent to calling <code>DebugPlugin.isUseStepFilters()</code>.
	 * </p>
	 * @return whether step filters are applied to step commands
	 * @since 3.0
	 * @see org.eclipse.debug.core.model.IStepFilters
	 */
	public static boolean isUseStepFilters() {
		return DebugPlugin.isUseStepFilters();
	}
		
	/**
	 * Returns the console associated with the given process, or 
	 * <code>null</code> if none.
	 * 
	 * @param process a process
	 * @return console associated with the given process, or 
	 * <code>null</code> if none
	 * @since 3.0
	 */
	public static IConsole getConsole(IProcess process) {
		return DebugUIPlugin.getDefault().getProcessConsoleManager().getConsole(process);
	}
	
	/**
	 * Returns the console associated with the given debug element, or 
	 * <code>null</code> if none.
	 * 
	 * @param element a debug model element
	 * @return console associated with the given element, or 
	 * <code>null</code> if none
	 * @since 3.0
	 */
	public static IConsole getConsole(IDebugElement element) {
		IProcess process = element.getDebugTarget().getProcess();
		if (process != null) {
			return getConsole(process);
		}
		return null;
	}	
	
	/**
	 * Returns all registered launch group extensions.
	 *  
	 * @return all registered launch group extensions
	 * @since 3.0
	 */
	public static ILaunchGroup[] getLaunchGroups() {
		return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroups();
	}
	
	/**
	 * Returns the last configuration that was launched for specified launch group or
	 * <code>null</code>, if there is not one. This method does not provide any form of
	 * filtering on the returned launch configurations.
	 * 
	 * @param groupId the unique identifier of a launch group
	 * @return the last launched configuration for the specified group or <code>null</code>.
	 * @see DebugUITools#getLaunchGroups()
	 * @since 3.3
	 */
	public static ILaunchConfiguration getLastLaunch(String groupId) {
		return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLastLaunch(groupId);
	}
	
	/**
	 * Returns the launch group that the given launch configuration belongs to, for the specified
	 * mode, or <code>null</code> if none.
	 * 
	 * @param configuration the launch configuration
	 * @param mode the mode
	 * @return the launch group the given launch configuration belongs to, for the specified mode,
	 *         or <code>null</code> if none
	 * @since 3.0
	 */
	public static ILaunchGroup getLaunchGroup(ILaunchConfiguration configuration, String mode) {
		try {
			return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(configuration.getType(), mode);
		}
		catch(CoreException ce) {
			return null;
		}
	}
	
    /**
     * Performs source lookup on the given artifact and returns the result.
     * Optionally, a source locator may be specified.
     *  
     * @param artifact object for which source is to be resolved
     * @param locator the source locator to use, or <code>null</code>. When <code>null</code>
     *   a source locator is determined from the artifact, if possible. If the artifact
     *   is a debug element, the source locator from its associated launch is used. 
     * @return a source lookup result
     * @since 3.1
     */
    public static ISourceLookupResult lookupSource(Object artifact, ISourceLocator locator) {	
		return SourceLookupFacility.getDefault().lookup(artifact, locator, false);
    }
	
    /**
     * Displays the given source lookup result in an editor in the given workbench
     * page. Has no effect if the result has an unknown editor id or editor input.
     * The editor is opened, positioned, and annotated.
     * <p>
     * Honors user preference for editors re-use.
     * </p> 
     * @param result source lookup result to display
     * @param page the page to display the result in
     * @since 3.1
     */
    public static void displaySource(ISourceLookupResult result, IWorkbenchPage page) {
    	SourceLookupFacility.getDefault().display(result, page);
    }
    
    /**
     * Returns the memory rendering manager.
     * 
     * @return the memory rendering manager
     * @since 3.1
     */
    public static IMemoryRenderingManager getMemoryRenderingManager() {
        return MemoryRenderingManager.getDefault();
    }
    
	/**
	 * Returns the image associated with the specified type of source container
	 * or <code>null</code> if none.
	 * 
	 * @param id unique identifier for a source container type
	 * @return image associated with the specified type of source container
	 *    or <code>null</code> if none
	 * @since 3.2
	 * @see org.eclipse.debug.core.sourcelookup.ISourceContainerType
	 */
	public static Image getSourceContainerImage(String id){
		return SourceLookupUIUtils.getSourceContainerImage(id);
	}
	
	/**
	 * Returns a new source container browser for the specified type of source container
	 * or <code>null</code> if a browser has not been registered.
	 * 
	 * @param id unique identifier for a source container type
	 * @return source container browser or <code>null</code> if none
	 * @since 3.2
	 * @see org.eclipse.debug.ui.sourcelookup.ISourceContainerBrowser
	 */
	public static ISourceContainerBrowser getSourceContainerBrowser(String id) {
		return SourceLookupUIUtils.getSourceContainerBrowser(id);
	}
	
	/**
	 * Returns the color associated with the specified preference identifier or 
	 * <code>null</code> if none.
	 * 
	 * @param id preference identifier of the color
	 * @return the color associated with the specified preference identifier
	 * 	or <code>null</code> if none
	 * @since 3.2
	 * @see IDebugUIConstants
	 */
	public static Color getPreferenceColor(String id) {
		return DebugUIPlugin.getPreferenceColor(id);
	}
	
	/**
	 * Returns the debug context manager.
	 * 
	 * @return debug context manager
	 * @since 3.3
	 */
	public static IDebugContextManager getDebugContextManager() {
		return DebugContextManager.getDefault();
	}

    /**
     * Return the debug context for the given executionEvent or <code>null</code> if none.
     * 
     * @param event The execution event that contains the application context
     * @return the current debug context, or <code>null</code>.
     * 
     * @since 3.5
     */
    public static ISelection getDebugContextForEvent(ExecutionEvent event) {
        Object o = HandlerUtil.getVariable(event, IConfigurationElementConstants.DEBUG_CONTEXT);
        if (o instanceof ISelection) {
            return (ISelection) o;
        }
        return null;
    }

    /**
     * Return the debug context for the given executionEvent.
     * 
     * @param event The execution event that contains the application context
     * @return the debug context. Will not return <code>null</code>.
     * @throws ExecutionException If the current selection variable is not found.
     * 
     * @since 3.5
     */
    public static ISelection getDebugContextForEventChecked(ExecutionEvent event)
            throws ExecutionException {
        Object o = HandlerUtil.getVariableChecked(event, IConfigurationElementConstants.DEBUG_CONTEXT);
        if (!(o instanceof ISelection)) {
            throw new ExecutionException("Incorrect type for " //$NON-NLS-1$
                + IConfigurationElementConstants.DEBUG_CONTEXT
                + " found while executing " //$NON-NLS-1$
                + event.getCommand().getId()
                + ", expected " + ISelection.class.getName() //$NON-NLS-1$
                + " found " + o.getClass().getName()); //$NON-NLS-1$
        }
        return (ISelection) o;
    }

    /**
     * Returns the global instance of toggle breakpoints target manager.
     * 
     * @return toggle breakpoints target manager
     * 
     * @since 3.8
     */
    public static IToggleBreakpointsTargetManager getToggleBreakpointsTargetManager() {
        return ToggleBreakpointsTargetManager.getDefault();
    }

}
