/*******************************************************************************
 * Copyright (c) 2006, 2007 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.views;

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

import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.commands.contexts.Context;
import org.eclipse.core.commands.contexts.ContextManagerEvent;
import org.eclipse.core.commands.contexts.IContextManagerListener;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
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.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.contexts.DebugModelContextBindingManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextService;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener4;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.contexts.IContextService;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Performs view management for a window.
 * 
 * @since 3.2
 */
public class ViewContextService implements IDebugContextListener, IPerspectiveListener4, IPropertyChangeListener, IContextManagerListener {
	
	/**
	 * Maps the perspectives in this window to its last activated workbench context
	 */
	private Map fPerspectiveToActiveContext = new HashMap();
	
	/**
	 * Map of the perspectives to all workbench contexts activated in that perspective 
	 */
	private Map fPerspectiveToActivatedContexts = new HashMap();
	
	/**
	 * Map of context id's to context view bindings
	 */
	private Map fContextIdsToBindings;
    	
	/**
	 * List of perspectives that debugging is allowed in
	 */
	private List fEnabledPerspectives = new ArrayList();	
    
    /**
     * Whether to ignore perspective change call backs (set to 
     * true when this class is modifying views). 
     */
    private boolean fIgnoreChanges = false;
	
	/**
	 * The window this service is working for
	 */
	private IWorkbenchWindow fWindow;
	
	private IContextService fContextService;
	
	// base debug context
	public static final String DEBUG_CONTEXT= "org.eclipse.debug.ui.debugging"; //$NON-NLS-1$
	
	// extension point
	private static final String ID_CONTEXT_VIEW_BINDINGS= "contextViewBindings"; //$NON-NLS-1$
	
	// extension attributes
	private static final String ATTR_CONTEXT_ID= "contextId"; //$NON-NLS-1$
	private static final String ATTR_VIEW_ID= "viewId"; //$NON-NLS-1$
	private static final String ATTR_AUTO_OPEN= "autoOpen"; //$NON-NLS-1$
	private static final String ATTR_AUTO_CLOSE= "autoClose"; //$NON-NLS-1$	
    
    // XML tags
    private static final String XML_ELEMENT_VIEW_BINDINGS ="viewBindings"; //$NON-NLS-1$
    private static final String XML_ELEMENT_PERSPECTIVE ="perspective"; //$NON-NLS-1$
    private static final String XML_ELEMENT_VIEW = "view"; //$NON-NLS-1$
    private static final String XML_ATTR_ID = "id"; //$NON-NLS-1$
    private static final String XML_ATTR_USER_ACTION = "userAction"; //$NON-NLS-1$
    private static final String XML_VALUE_OPENED = "opened"; //$NON-NLS-1$
    private static final String XML_VALUE_CLOSED = "closed"; //$NON-NLS-1$
    
    // ids of base debug views in debug perspective that should not be auto-closed
    private static Set fgBaseDebugViewIds = null;
    
    static {
        fgBaseDebugViewIds = new HashSet();
        fgBaseDebugViewIds.add(IDebugUIConstants.ID_DEBUG_VIEW);
        fgBaseDebugViewIds.add(IDebugUIConstants.ID_VARIABLE_VIEW);
        fgBaseDebugViewIds.add(IDebugUIConstants.ID_BREAKPOINT_VIEW);
        fgBaseDebugViewIds.add(IConsoleConstants.ID_CONSOLE_VIEW);
    }
    
    private static String[] EMPTY_IDS = new String[0];
    
    /**
     * View bindings for a debug context
     */
    private class DebugContextViewBindings {
    	
    	// context id
    	private String fId;
    	
    	// list of view bindings id's specific to this context
    	private String[] fViewBindingIds = EMPTY_IDS;
    	
    	// all bindings including inherited bindings, top down in activation order
    	private String[] fAllViewBindingIds = null;
    	// associated binding to activate
    	private Map fAllViewIdToBindings = new HashMap();
    	// all context id's in this context hierarchy (top down order)
    	private String[] fAllConetxtIds = null;

    	// id of parent context
    	private String fParentId;
    	
    	/**
    	 * Constructs an empty view binding for the given context.
    	 * 
    	 * @param id context id
    	 */
    	public DebugContextViewBindings(String id) {
    		fId = id;
    	}
    	
    	/**
    	 * Returns the context id for these view bindings
    	 * 
    	 * @return context id
    	 */
    	public String getId() {
    		return fId;
    	}
    	
    	/**
    	 * Adds the given view binding to this context
    	 * 
    	 * @param binding view binding to add
    	 */
    	public void addBinding(ViewBinding binding) {
    		String[] newBindings = new String[fViewBindingIds.length + 1];
    		System.arraycopy(fViewBindingIds, 0, newBindings, 0, fViewBindingIds.length);
    		newBindings[fViewBindingIds.length] = binding.getViewId();
    		fAllViewIdToBindings.put(binding.getViewId(), binding);
    		fViewBindingIds = newBindings;
    	}
    	
    	/**
    	 * Sets the parent id of this view bindings
    	 * 
    	 * @param id parent context id
    	 */
    	protected void setParentId(String id) {
    		fParentId = id;
    	}
    	
    	/**
    	 * Returns the id of parent context
    	 * 
    	 * @return parent context id
    	 */
    	public DebugContextViewBindings getParentContext() {
    		if (fParentId == null) {
    			return null;
    		}
    		return (DebugContextViewBindings) fContextIdsToBindings.get(fParentId);
    	}
    	
    	/**
    	 * Activates the views in this context hierarchy. Views are activated top down, allowing
    	 * sub-contexts to override settings in a parent context.
    	 */
    	public void activateChain(IWorkbenchPage page) {
    		initializeChain();
    		doActivation(page, fAllViewBindingIds, fAllConetxtIds);
    	}	
    	
    	/**
    	 * Activates the view bindings for the specified views and the 
    	 * specified contexts in the given page.
    	 *  
    	 * @param page page to activate views in
    	 * @param viewIds id's of views to activate
    	 * @param contextIds associated contexts that are activated
    	 */
    	private void doActivation(IWorkbenchPage page, String[] viewIds, String[] contextIds) {
    		// note activation of all the relevant contexts
    		for (int i = 0; i < contextIds.length; i++) {
				addActivated(contextIds[i]);
			}
    		// set the active context to be this
    		setActive(page.getPerspective(), getId());
    		// activate the view bindings
    		for (int i = 0; i < viewIds.length; i++) {
				String viewId = viewIds[i];
				ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
				binding.activated(page);
			}
    		// bring most relevant views to top
    		for (int i = 0; i < viewIds.length; i++) {
				String viewId = viewIds[i];
				ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
				binding.checkZOrder(page, fAllViewBindingIds);
			}
    	}
    	
    	/**
    	 * Builds the top down ordered list of bindings for this context allowing sub-contexts
    	 * to override parent settings.
    	 */
    	private synchronized void initializeChain() {
    		if (fAllViewBindingIds == null) {
    			List orderedIds = new ArrayList();
    			List contexts = new ArrayList();
    			DebugContextViewBindings context = this;
    			while (context != null) {
    				contexts.add(0, context);
    				context = context.getParentContext();
    			}
    			Iterator iterator = contexts.iterator();
    			fAllConetxtIds = new String[contexts.size()];
    			int pos = 0;
    			while (iterator.hasNext()) {
    				DebugContextViewBindings bindings = (DebugContextViewBindings) iterator.next();
    				fAllConetxtIds[pos] = bindings.getId();
    				pos++;
    				for (int i = 0; i < bindings.fViewBindingIds.length; i++) {
						String viewId = bindings.fViewBindingIds[i];
    					if (bindings == this) {
    						orderedIds.add(viewId);
    					}
    					if (!fAllViewIdToBindings.containsKey(viewId)) {
    						orderedIds.add(viewId);
    						fAllViewIdToBindings.put(viewId, bindings.fAllViewIdToBindings.get(viewId));
    					}
					}
    			}
    			fAllViewBindingIds = (String[]) orderedIds.toArray(new String[orderedIds.size()]);
    		}
    	}
    	
    	/**
    	 * Deactivates this context only (not parents)
    	 * 
    	 * @param page workbench page
    	 */
    	public void deactivate(IWorkbenchPage page) {
			removeActivated(getId());
			if (isActiveContext(getId())) {
				setActive(page.getPerspective(), null);
			}
			for (int i = 0; i < fViewBindingIds.length; i++) {
				String viewId = fViewBindingIds[i];
				ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
				binding.deactivated(page);
			}
    	}
    	
    	/**
    	 * Notes when a view is opened/closed manually.
    	 * 
    	 * @param opened opened or closed
    	 * @param viewId
    	 */
    	public void setViewOpened(boolean opened, String viewId) {
    		initializeChain();
    		ViewBinding binding = (ViewBinding)fAllViewIdToBindings.get(viewId);
    		if (binding != null) {
    			if (opened) {
    				binding.userOpened();
    			} else {
    				binding.userClosed();
    			}
    		}
    	}

        public void applyUserSettings(String viewId, Element viewElement) {
        	initializeChain();
        	ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
        	if (binding != null) {
        		binding.applyUserSettings(viewElement);
        	}
        }    	
    	
        /**
         * Save view binding settings into XML document.
         * 
         * @param document
         * @param root
         * @param alreadyDone views already done
         */
        public void saveBindings(Document document, Element root, Set alreadyDone) {
        	for (int i = 0; i < fViewBindingIds.length; i++) {
				String viewId = fViewBindingIds[i];
        		if (!alreadyDone.contains(viewId)) {
        			alreadyDone.add(viewId);
        			ViewBinding binding = (ViewBinding) fAllViewIdToBindings.get(viewId);
        			binding.saveBindings(document, root);
        		}
			}
        }    	
    }
    
    /**
     * Information for a view
     */
    private class ViewBinding {
        private IConfigurationElement fElement;
        /**
         * Set of perspectives this view was opened in by the user
         */
        private Set fUserOpened = new HashSet();
        /**
         * Set of perspectives this view was closed in by the user
         */
        private Set fUserClosed = new HashSet();
        
        public ViewBinding(IConfigurationElement element) {
            fElement = element;
        }
        
        /**
         * Returns the id of the view this binding pertains to.
         * 
         * @return
         */
        public String getViewId() {
            return fElement.getAttribute(ATTR_VIEW_ID);
        }
        
        /**
         * Returns whether this view binding is set for auto-open.
         * 
         * @return
         */
        public boolean isAutoOpen() {
            String autoopen = fElement.getAttribute(ATTR_AUTO_OPEN);
            return autoopen == null || "true".equals(autoopen); //$NON-NLS-1$
        }
        
        /**
         * Returns whether this view binding is set for auto-close.
         * 
         * @return
         */
        public boolean isAutoClose() {
            String autoclose = fElement.getAttribute(ATTR_AUTO_CLOSE);
            return autoclose == null || "true".equals(autoclose); //$NON-NLS-1$
        }
        
        /**
         * Returns whether this view was opened by the user in the active perspective.
         * @return
         */
        public boolean isUserOpened() {
            return fUserOpened.contains(getActivePerspective().getId());
        }
        
        /**
         * Returns whether this view was closed by the user in the active perspective
         * @return
         */
        public boolean isUserClosed() {
            return fUserClosed.contains(getActivePerspective().getId());
        }
        
        /**
         * Returns whether this view is part of the active perspective by default
         * 
         * TODO: we really need an API to determine which views are
         * in a perspective by default, but it does not seem to exist.
         * 
         * @return
         */
        public boolean isDefault() {
            String id = getActivePerspective().getId();
            if (IDebugUIConstants.ID_DEBUG_PERSPECTIVE.equals(id)) {
                return fgBaseDebugViewIds.contains(getViewId());
            }
            return false;
        }
        
        protected void userOpened() {
            if (isTrackingViews()) {
                String id = getActivePerspective().getId();
                fUserOpened.add(id);
                fUserClosed.remove(id);
                saveViewBindings();
            }
        }
        
        protected void userClosed() {
            if (isTrackingViews()) {
                String id = getActivePerspective().getId();
                fUserClosed.add(id);
                fUserOpened.remove(id);
                saveViewBindings();
            }
        }
        
        /**
         * Returns whether the preference is set to track user view open/close.
         * 
         * @return
         */
        protected boolean isTrackingViews() {
            return DebugUITools.getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_TRACK_VIEWS);
        }
        
        /**
         * Context has been activated, open/show as required.
         * 
         * @param page
         */
        public void activated(IWorkbenchPage page) {
            if (!isUserClosed()) {
                if (isAutoOpen()) {
                    try {
                        fIgnoreChanges = true;
                        page.showView(getViewId(), null, IWorkbenchPage.VIEW_CREATE);
                    } catch (PartInitException e) {
                        DebugUIPlugin.log(e);
                    } finally {
                        fIgnoreChanges = false;
                    }
                }
            }
        }
        
        /**
         * Context has been activated. Check the view stack to see if this view
         * should be made visible.
         * 
         * @param page
         */
        public void checkZOrder(IWorkbenchPage page, String[] relevantViews) {
        	// see if view is open already
        	IViewPart part = page.findView(getViewId());
        	if (part != null) {
        		IViewPart[] viewStack = page.getViewStack(part);
        		if (viewStack != null && viewStack.length > 0) {
        			String top = viewStack[0].getSite().getId();
        			for (int i = 0; i < relevantViews.length; i++) {
						if (relevantViews[i].equals(top)) {
							// a relevant view is visible
							return;
						}
					}
        			// an irrelevant view is visible
                    try {
                        fIgnoreChanges = true;
                        page.bringToTop(part);
                    } finally {
                        fIgnoreChanges = false;
                    }
        		}
        	}
        }        
        
        /**
         * Context has been deactivated, close as required.
         * 
         * @param page
         */
        public void deactivated(IWorkbenchPage page) {
            if (!isUserOpened()) {
                if (isAutoClose() && !isDefault()) {
                    IViewReference reference = page.findViewReference(getViewId());
                    if (reference != null) {
                        try {
                            fIgnoreChanges = true;
                            page.hideView(reference);
                        } finally {
                            fIgnoreChanges = false;
                        }
                    }
                }
            }
        }

        /**
         * Save view binding settings into XML document.
         * 
         * @param document
         * @param root
         */
        public void saveBindings(Document document, Element root) {
            Element viewElement = document.createElement(XML_ELEMENT_VIEW);
            viewElement.setAttribute(XML_ATTR_ID, getViewId());
            appendPerspectives(document, viewElement, fUserOpened, XML_VALUE_OPENED);
            appendPerspectives(document, viewElement, fUserClosed, XML_VALUE_CLOSED);
            if (viewElement.hasChildNodes()) {
                root.appendChild(viewElement);
            }
        }
        
        private void appendPerspectives(Document document, Element parent, Set perpectives, String xmlValue) {
            String[] ids = (String[]) perpectives.toArray(new String[perpectives.size()]);
            for (int i = 0; i < ids.length; i++) {
                String id = ids[i];
                Element element = document.createElement(XML_ELEMENT_PERSPECTIVE);
                element.setAttribute(XML_ATTR_ID, id);
                element.setAttribute(XML_ATTR_USER_ACTION, xmlValue);
                parent.appendChild(element);
            }
        }
        
        public void applyUserSettings(Element viewElement) {
            NodeList list = viewElement.getChildNodes();
            int length = list.getLength();
            for (int i = 0; i < length; ++i) {
                Node node = list.item(i);
                short type = node.getNodeType();
                if (type == Node.ELEMENT_NODE) {
                    Element entry = (Element) node;
                    if(entry.getNodeName().equalsIgnoreCase(XML_ELEMENT_PERSPECTIVE)){
                        String id = entry.getAttribute(XML_ATTR_ID);
                        String setting = entry.getAttribute(XML_ATTR_USER_ACTION);
                        if (id != null) {
                            if (XML_VALUE_CLOSED.equals(setting)) {
                                fUserClosed.add(id);
                            } else if (XML_VALUE_OPENED.equals(setting)) {
                                fUserOpened.add(id);
                            }
                        }
                    }
                }
            }       
        }
    }
    
    private IDebugContextService getDebugContextService() {
    	return DebugUITools.getDebugContextManager().getContextService(fWindow);
    }
	
	/**
	 * Creates a service for the given window
	 * 
	 * @param window
	 */
	ViewContextService(IWorkbenchWindow window) {
		fWindow = window;
		fContextService = (IContextService) PlatformUI.getWorkbench().getAdapter(IContextService.class);
		loadContextToViewExtensions();
        applyUserViewBindings();
		loadPerspectives();
		window.addPerspectiveListener(this);
		getDebugContextService().addDebugContextListener(this);
		DebugUIPlugin.getDefault().getPluginPreferences().addPropertyChangeListener(this);
		fContextService.addContextManagerListener(this);
	}
	
	public void dispose() {
		fWindow.removePerspectiveListener(this);
		getDebugContextService().removeDebugContextListener(this);
		DebugUIPlugin.getDefault().getPluginPreferences().removePropertyChangeListener(this);
		fContextService.removeContextManagerListener(this);
	}
	
	/**
	 * Loads extensions which map context id's to view bindings.
	 */
	private void loadContextToViewExtensions() {
        fContextIdsToBindings = new HashMap();
		IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), ID_CONTEXT_VIEW_BINDINGS);
		IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements();
		for (int i = 0; i < configurationElements.length; i++) {
			IConfigurationElement element = configurationElements[i];
			String viewId = element.getAttribute(ATTR_VIEW_ID);
			String contextId = element.getAttribute(ATTR_CONTEXT_ID);
			if (contextId == null || viewId == null) {
				continue;
			}
            ViewBinding info = new ViewBinding(element);
			DebugContextViewBindings bindings = (DebugContextViewBindings) fContextIdsToBindings.get(contextId);
			if (bindings == null) {
				bindings = new DebugContextViewBindings(contextId);
				fContextIdsToBindings.put(contextId, bindings);
			}
			bindings.addBinding(info);
		}
		linkParentContexts();
	}
    
    /**
     * Applies user settings that modify view binding extensions.
     */
    private void applyUserViewBindings() {
        String xml = DebugUITools.getPreferenceStore().getString(IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS);
        if (xml.length() > 0) {
            try {
                Element root = DebugPlugin.parseDocument(xml);
                NodeList list = root.getChildNodes();
                int length = list.getLength();
                for (int i = 0; i < length; ++i) {
                    Node node = list.item(i);
                    short type = node.getNodeType();
                    if (type == Node.ELEMENT_NODE) {
                        Element entry = (Element) node;
                        if(entry.getNodeName().equalsIgnoreCase(XML_ELEMENT_VIEW)){
                            String id = entry.getAttribute(XML_ATTR_ID);
                            Iterator bindings = fContextIdsToBindings.values().iterator();
                            while (bindings.hasNext()) {
                            	DebugContextViewBindings binding = (DebugContextViewBindings) bindings.next();
                            	binding.applyUserSettings(id, entry);
                            }
                        }
                    }
                }                
            } catch (CoreException e) {
                DebugUIPlugin.log(e);
            }
        }
    }
	
	/**
	 * Load the collection of perspectives in which view management will occur from the preference store.
	 */
	private void loadPerspectives() {
		String prefString = DebugUIPlugin.getDefault().getPreferenceStore().getString(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES);
		fEnabledPerspectives = parseList(prefString);
	}	
	
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
        if (!fIgnoreChanges) {
    		if (IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES.equals(event.getProperty())) {
    			loadPerspectives();
    		} else if (IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS.equals(event.getProperty())) {
    		    loadContextToViewExtensions();
                applyUserViewBindings();
                // clear activations to re-enable activation based on new settings
                fPerspectiveToActivatedContexts.clear();
                ISelection selection = getDebugContextService().getActiveContext();
                contextActivated(selection);
            }
        }
	}	
	
	/**
	 * Returns whether this service's window's active perspective supports view management.
	 * 
	 * @return whether this service's window's active perspective supports view management
	 */
	private boolean isEnabledPerspective() {
		IPerspectiveDescriptor perspective = getActivePerspective();
		if (perspective != null) {
			return fEnabledPerspectives.contains(perspective.getId());
		}
		return false;
	}	
	
	/**
	 * Returns the active perspective in this service's window, or <code>null</code>
	 * 
	 * @return active perspective or <code>null</code>
	 */
	private IPerspectiveDescriptor getActivePerspective() {
		IWorkbenchPage activePage = fWindow.getActivePage();
		if (activePage != null) {
			return activePage.getPerspective();
		}
		return null;
	}
	
	/**
	 * Parses the comma separated string into a list of strings
	 * 
	 * @return list
	 */
	public static List parseList(String listString) {
		List list = new ArrayList(10);
		StringTokenizer tokenizer = new StringTokenizer(listString, ","); //$NON-NLS-1$
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			list.add(token);
		}
		return list;
	}
	
	public void contextActivated(ISelection selection) {
		if (isEnabledPerspective()) {
			if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
				IStructuredSelection ss = (IStructuredSelection) selection;
				Iterator iterator = ss.iterator();
				while (iterator.hasNext()) {
					Object target = iterator.next();
					ILaunch launch = DebugModelContextBindingManager.getLaunch(target);
					if (launch != null) {
						ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
						if (launchConfiguration != null) {
							try {
								ILaunchConfigurationType type = launchConfiguration.getType();
								// check if this perspective is enabled for the launch type
								// Include the word '.internal.' so the context is filtered from the key binding pref page (Bug 144019) also see PerspectiveManager.handleBreakpointHit()
								if (fContextService.getActiveContextIds().contains(type.getIdentifier() + ".internal." + getActivePerspective().getId())) { //$NON-NLS-1$
									// get the leaf contexts to be activated
									List workbenchContexts = DebugModelContextBindingManager.getDefault().getWorkbenchContextsForDebugContext(target);
									// TODO: do we need to check if contexts are actually enabled in workbench first?
									if (!workbenchContexts.isEmpty()) {
										// if all contexts already activate and last context is already active context == done
										Iterator contexts = workbenchContexts.iterator();
										while (contexts.hasNext()) {
											String contextId = (String)contexts.next();
											if (!isActivated(contextId)) {
												activateChain(contextId);
											}
											// ensure last context gets top priority
											if (!contexts.hasNext()) {
												if (!isActiveContext(contextId)) {
													activateChain(contextId);
												}
											}
										}
									}
									
								}
							} catch (CoreException e) {
								DebugUIPlugin.log(e);
							}
						}												
					}						
				}
			}
		}
	}
	
	/**
	 * Returns whether the given context is the active context in the active perspective.
	 * 
	 * @param contextId
	 * @return
	 */
	private boolean isActiveContext(String contextId) {
		IPerspectiveDescriptor activePerspective = getActivePerspective();
		if (activePerspective != null) {
			String activeId = (String) fPerspectiveToActiveContext.get(activePerspective);
			return contextId.equals(activeId);
		}
		return false;
	}
	
	/**
	 * Returns whether the given context is activated in the active perspective. 
	 * 
	 * @param contextId
	 * @return
	 */
	private boolean isActivated(String contextId) {
		IPerspectiveDescriptor activePerspective = getActivePerspective();
		if (activePerspective != null) {
			Set contexts = (Set) fPerspectiveToActivatedContexts.get(activePerspective); 
			if (contexts != null) {
				return contexts.contains(contextId);
			}
		}
		return false;
	}
	
	private void addActivated(String contextId) {
		IPerspectiveDescriptor activePerspective = getActivePerspective();
		if (activePerspective != null) {
			Set contexts = (Set) fPerspectiveToActivatedContexts.get(activePerspective); 
			if (contexts == null) {
				contexts = new HashSet();
				fPerspectiveToActivatedContexts.put(activePerspective, contexts);
			}
			contexts.add(contextId);
		}
	}
	
	private void removeActivated(String contextId) {
		IPerspectiveDescriptor activePerspective = getActivePerspective();
		if (activePerspective != null) {
			Set contexts = (Set) fPerspectiveToActivatedContexts.get(activePerspective); 
			if (contexts != null) {
				contexts.remove(contextId);
			}
		}		
	}

	public void debugContextChanged(DebugContextEvent event) {
		if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) {
			contextActivated(event.getContext());
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveOpened(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveOpened(IWorkbenchPage page, IPerspectiveDescriptor perspective) {        
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveClosed(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveClosed(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveDeactivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveDeactivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
	}
	
	/**
	 * Closes all auto-opened views.
	 * 
	 * @param page
	 * @param perspective
	 */
	private void clean(IPerspectiveDescriptor perspective) {
		Set contexts = (Set) fPerspectiveToActivatedContexts.remove(perspective);
		fPerspectiveToActiveContext.remove(perspective);
		if (contexts != null) {
			Iterator iterator = contexts.iterator();
			while (iterator.hasNext()) {
				String id = (String) iterator.next();
				deactivate(id);
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener3#perspectiveSavedAs(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveSavedAs(IWorkbenchPage page, IPerspectiveDescriptor oldPerspective, IPerspectiveDescriptor newPerspective) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String)
	 */
	public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) {
		if (!fIgnoreChanges && page.getWorkbenchWindow().equals(fWindow)) {
			if(partRef != null) {
                if (IWorkbenchPage.CHANGE_VIEW_SHOW == changeId || IWorkbenchPage.CHANGE_VIEW_HIDE == changeId) {
                	Iterator iterator = fContextIdsToBindings.values().iterator();
                	while (iterator.hasNext()) {
                		DebugContextViewBindings bindings = (DebugContextViewBindings) iterator.next();
                		bindings.setViewOpened(IWorkbenchPage.CHANGE_VIEW_SHOW == changeId, partRef.getId());
                	}
                }
			}
        }	
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
		if (page.getWorkbenchWindow().equals(fWindow)) {
			ISelection activeContext = getDebugContextService().getActiveContext();
			if (activeContext != null) {
				contextActivated(activeContext);
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String)
	 */
	public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) {
	}
	
	/**
	 * Activates all parent contexts of the given context, top down.
	 * 
	 * @param contextId
	 */
	private void activateChain(String contextId) {
		IWorkbenchPage page = fWindow.getActivePage();
		if (page != null) {
			DebugContextViewBindings bindings= (DebugContextViewBindings) fContextIdsToBindings.get(contextId);
			if (bindings != null) {
				bindings.activateChain(page);
			}
		}
	}
	
	/**
	 * Links each debug context view bindings with its parent context bindings 
	 */
	private void linkParentContexts() {
		Iterator iterator = fContextIdsToBindings.entrySet().iterator();
		while (iterator.hasNext()) {
			Entry entry = (Entry)iterator.next();
			String contextId = (String) entry.getKey();
			DebugContextViewBindings bindings = (DebugContextViewBindings) entry.getValue();
			if (!bindings.getId().equals(DEBUG_CONTEXT)) {
				Context context = fContextService.getContext(contextId);
				try {
					bindings.setParentId(context.getParentId());
				} catch (NotDefinedException e) {
					DebugUIPlugin.log(e);
				}
			}
		}
	}	
	
	/**
	 * Sets the active context in the given perspective, or removes
	 * when <code>null</code>.
	 * 
	 * @param perspective
	 * @param contextId
	 */
	private void setActive(IPerspectiveDescriptor perspective, String contextId) {
		if (contextId == null) {
			fPerspectiveToActiveContext.remove(perspective);
		} else {
			fPerspectiveToActiveContext.put(perspective, contextId);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.commands.contexts.IContextManagerListener#contextManagerChanged(org.eclipse.core.commands.contexts.ContextManagerEvent)
	 */
	public void contextManagerChanged(ContextManagerEvent event) {
		if (event.isActiveContextsChanged()) {
			Set disabledContexts = getDisabledContexts(event);
			if (!disabledContexts.isEmpty()) {
				Iterator contexts = disabledContexts.iterator();
				while (contexts.hasNext()) {
					String contextId = (String)contexts.next();
					if (isViewConetxt(contextId)) {
						if (isActivated(contextId)) {
							deactivate(contextId);
						}
					}
				}
			}
		}
	}
	
	private void deactivate(String contextId) {
		IWorkbenchPage page = fWindow.getActivePage();
		if (page != null) {
			DebugContextViewBindings bindings = (DebugContextViewBindings) fContextIdsToBindings.get(contextId);
			if (bindings != null) {
				bindings.deactivate(page);
			}
		}		
	}
	
	/**
	 * Returns a set of contexts disabled in the given event, possibly empty.
	 * 
	 * @param event
	 * @return disabled context id's
	 */
	private Set getDisabledContexts(ContextManagerEvent event) {
		Set prev = new HashSet(event.getPreviouslyActiveContextIds());
		Set activeContextIds = event.getContextManager().getActiveContextIds();
		if (activeContextIds != null) {
			prev.removeAll(activeContextIds);
		}
		return prev;
	}	

	/**
	 * Returns whether the given context has view bindings.
	 * 
	 * @param id
	 * @return whether the given context has view bindings
	 */
	private boolean isViewConetxt(String id) {
		return fContextIdsToBindings.containsKey(id);
	}
    
    /**
     * Save view binding settings that differ from extension settings
     */
    private void saveViewBindings() {
        try {
            Document document = DebugPlugin.newDocument();
            Element root = document.createElement(XML_ELEMENT_VIEW_BINDINGS);
            document.appendChild(root);
            Set done = new HashSet();
            Iterator bindings = fContextIdsToBindings.values().iterator();
            while (bindings.hasNext()) {
                DebugContextViewBindings binding = (DebugContextViewBindings) bindings.next();
                binding.saveBindings(document, root, done);
            }
            String prefValue = ""; //$NON-NLS-1$
            if (root.hasChildNodes()) {
            	prefValue = DebugPlugin.serializeDocument(document);
            }
            fIgnoreChanges = true;
            DebugUITools.getPreferenceStore().setValue(IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS, prefValue);
        } catch (CoreException e) {
            DebugUIPlugin.log(e);
        } finally {
            fIgnoreChanges = false;
        }

    }    
    
    /**
     * Returns the perspectives in which debugging is enabled.
     * 
     * @return
     */
    public String[] getEnabledPerspectives() {
    	return (String[]) fEnabledPerspectives.toArray(new String[fEnabledPerspectives.size()]);
    }
    
    /**
     * Show the view without effecting user preferences
     * 
     * @param viewId
     */
    public void showViewQuiet(String viewId) {
		IWorkbenchPage page = fWindow.getActivePage();
		if (page != null) {
			try {
				fIgnoreChanges = true;
				IViewPart part = page.showView(viewId, null, IWorkbenchPage.VIEW_VISIBLE);
				if (!page.isPartVisible(part)) {
					page.bringToTop(part);
				}
			} catch (PartInitException e) {
				DebugUIPlugin.log(e);
			} finally {
				fIgnoreChanges = false;
			}
		}    	
    }

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IPerspectiveListener4#perspectivePreDeactivate(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
	 */
	public void perspectivePreDeactivate(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
		if (page.getWorkbenchWindow().equals(fWindow)) {
			clean(perspective);
		}
	}
}
