/*******************************************************************************
 * Copyright (c) 2008 Wind River Systems 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
 *     Wind River Systems - adapted to use with IToggleBreakpiontsTargetFactory extension
 *******************************************************************************/
package org.eclipse.debug.internal.ui.actions;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
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.expressions.EvaluationContext;
import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionConverter;
import org.eclipse.core.expressions.ExpressionTagNames;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.internal.core.IConfigurationElementConstants;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.services.IEvaluationService;

/**
 * Organizes the toggle breakpoints target factories contributed through the 
 * extension point and keeps track of the toggle breakpoints target that 
 * the factories produce.  The manager is accessed as a singleton through
 * the <code>getDefault()</code> method.
 * <p>
 * The adapter mechanism for obtaining a toggle breakpoints target is
 * still supported through a specialized toggle target factory.  Targets
 * contributed through this mechanism are labeled as "Default" in the UI. 
 * </p>  
 * 
 * @see IToggleBreakpointsTargetFactory
 * @see IToggleBreakpointsTarget
 * @see IToggleBreakpointsTargetExtension
 * @since 3.5
 */
public class ToggleBreakpointsTargetManager {

    /**
     * Toggle breakpoints target ID which refers to a target contributed
     * through the legacy adapter mechanism.
     */
    public static String DEFAULT_TOGGLE_TARGET_ID = "default"; //$NON-NLS-1$
    
    private static Set DEFAULT_TOGGLE_TARGET_ID_SET = new HashSet();
    static {
        DEFAULT_TOGGLE_TARGET_ID_SET.add(DEFAULT_TOGGLE_TARGET_ID);
    }
    
    /**
     * Acts as a proxy between the toggle breakpoints target manager and the factories 
     * contributed to the extension point.  Only loads information from the plug-in xml 
     * and only instantiates the specified factory if required (lazy loading).
     */
    private static class ToggleTargetFactory implements IToggleBreakpointsTargetFactory {
        
        private IConfigurationElement fConfigElement;
        private IToggleBreakpointsTargetFactory fFactory;
        private Expression fEnablementExpression;
        
        public ToggleTargetFactory(IConfigurationElement configElement){
            fConfigElement = configElement;         
        }

        /**
         * Returns the instantiated factory specified by the class property. 
         */
        private IToggleBreakpointsTargetFactory getFactory() {
            if (fFactory != null) return fFactory;
            try{
                Object obj = fConfigElement.createExecutableExtension(IConfigurationElementConstants.CLASS);
                if(obj instanceof IToggleBreakpointsTargetFactory) {
                    fFactory = (IToggleBreakpointsTargetFactory)obj;
                } else {
                    throw new CoreException(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "org.eclipse.debug.ui.toggleBreakpointsTargetFactories extension failed to load breakpoint toggle target because the specified class does not implement org.eclipse.debug.ui.actions.IToggleBreakpointsTargetFactory.  Class specified was: " + obj, null)); //$NON-NLS-1$
                }   
            } catch (CoreException e){
                DebugUIPlugin.log(e.getStatus());
                fFactory = null;
            }
            return fFactory;
        }
        
        /**
         * Checks if the enablement expression for the factory evaluates to true for the
         * given part and selection.
         */
        public boolean isEnabled(IWorkbenchPart part, ISelection selection) {
            boolean enabled = false;
            Expression expression = getEnablementExpression();
            if (expression != null) {
                enabled = evalEnablementExpression(part, selection, expression);
            } else {
                enabled = true;
            }
            return enabled;
        }
        
        /**
         * Returns the active debug context given the active part.  It is used
         * in creating the evaluation context for the factories' enablement expression. 
         * @param part active part
         * @return current active debug context
         */
        private IStructuredSelection getDebugContext(IWorkbenchPart part) {
            ISelection selection = DebugUITools.getDebugContextManager().
                getContextService(part.getSite().getWorkbenchWindow()).getActiveContext();
            if (selection instanceof IStructuredSelection) {
                return (IStructuredSelection)selection;
            } 
            return StructuredSelection.EMPTY;
        }

        /**
         * Evaluate the given expression within the given context and return
         * the result. Returns <code>true</code> iff result is either TRUE.
         * 
         * @param exp the enablement expression to evaluate or <code>null</code>
         * @param context the context of the evaluation. Usually, the
         *  user's selection.
         * @return the result of evaluating the expression
         */
        private boolean evalEnablementExpression(IWorkbenchPart part, ISelection selection, Expression exp) {
            if (exp != null){
        		IEvaluationContext parentContext = null;
        		IEvaluationService evaluationService = (IEvaluationService)PlatformUI.getWorkbench().getService(IEvaluationService.class);
        		if (evaluationService != null) {
        			parentContext = evaluationService.getCurrentState();
        		}
                IEvaluationContext context = new EvaluationContext(parentContext, part);
                
                List debugContextList = getDebugContext(part).toList();
                context.addVariable(IConfigurationElementConstants.DEBUG_CONTEXT, debugContextList); 

                if (selection instanceof IStructuredSelection) {
                    List selectionList = ((IStructuredSelection)selection).toList();
                    context.addVariable(IConfigurationElementConstants.SELECTION, selectionList); 
                }

                if (part instanceof IEditorPart) {
                    context.addVariable(IConfigurationElementConstants.EDITOR_INPUT, ((IEditorPart)part).getEditorInput());
                }
                
                try{
                    EvaluationResult result = exp.evaluate(context);
                    if (result == EvaluationResult.TRUE){
                        return true;
                    }
                } catch (CoreException e){
                    // Evaluation failed
                }
            }
            return false;
        }
        
        /**
         * Returns an expression that represents the enablement logic for the
         * breakpiont toggle target.
         */
        private Expression getEnablementExpression(){
            if (fEnablementExpression == null) {
                try{
                    IConfigurationElement[] elements = fConfigElement.getChildren(ExpressionTagNames.ENABLEMENT);
                    IConfigurationElement enablement = elements.length > 0 ? elements[0] : null; 
                    if (enablement != null) {
                        fEnablementExpression = ExpressionConverter.getDefault().perform(enablement);
                    }
                } catch (CoreException e){
                    DebugUIPlugin.log(e.getStatus());
                    fEnablementExpression = null;
                }
            }
            return fEnablementExpression;
        }

        /** 
         * Instantiates the factory and asks it to produce the IToggleBreakpointsTarget
         * for the given ID
         */
        public IToggleBreakpointsTarget createToggleTarget(String targetID) {
            IToggleBreakpointsTargetFactory factory = getFactory();
            if (factory != null) {
                return factory.createToggleTarget(targetID);
            } 
            return null;
        }
        
        /** 
         * Instantiates the factory and asks it for the set of toggle target
         * IDs that the factory can produce for the given part and selection.
         */
        public Set getToggleTargets(IWorkbenchPart part, ISelection selection) {
            IToggleBreakpointsTargetFactory factory = getFactory();
            if (factory != null) {
                return factory.getToggleTargets(part, selection);
            } 
            return Collections.EMPTY_SET;
        }

        /** 
         * Instantiates the factory and asks it to produce the name of the toggle target
         * for the given ID.
         */
        public String getToggleTargetName(String targetID) {
            IToggleBreakpointsTargetFactory factory = getFactory();
            if (factory != null) {
                return factory.getToggleTargetName(targetID);
            } 
            return null;
        }

        /** 
         * Instantiates the factory and asks it to produce the description of the toggle 
         * target for the given ID.
         */
        public String getToggleTargetDescription(String targetID) {
            IToggleBreakpointsTargetFactory factory = getFactory();
            if (factory != null) {
                return factory.getToggleTargetDescription(targetID);
            } 
            return null;
        }
        
        /** 
         * Instantiates the factory and asks it for the toggle tareget ID that
         * the factory considers the default for the given part and selection.
         */
        public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) { 
            IToggleBreakpointsTargetFactory factory = getFactory();
            if (factory != null) {
                return factory.getDefaultToggleTarget(part, selection);
            } 
            return null;
        }
    }

    
    /**
     * Factory for toggle breakpoints targets contributed through the
     * adapter mechanism.  
     */
    private static class ToggleBreakpointsTargetAdapterFactory implements IToggleBreakpointsTargetFactory {

        private IAdaptable getAdaptable(IWorkbenchPart part, ISelection selection) {
            IAdaptable adaptable = null;
            if (selection instanceof IStructuredSelection) {
                IStructuredSelection ss = (IStructuredSelection)selection; 
                if (ss.getFirstElement() instanceof IAdaptable) {
                    adaptable = (IAdaptable) ss.getFirstElement();
                }
            } else {
                adaptable = part;
            }
            return adaptable;
        }
        
        private boolean canGetToggleBreakpointsTarget(IAdaptable adaptable) {
            if (adaptable != null) {
                IToggleBreakpointsTarget adapter = (IToggleBreakpointsTarget) 
                    adaptable.getAdapter(IToggleBreakpointsTarget.class);
                if (adapter == null) {
                    IAdapterManager adapterManager = Platform.getAdapterManager();
                    if (adapterManager.hasAdapter(adaptable, IToggleBreakpointsTarget.class.getName())) {
                        return true;
                    }
                } else {
                    return true;
                }
            }
            return false;
        }
        
        /**
         * Finds the toggle breakpoints target for the active part and selection.  
         * It first looks for the target using the factories registered using an 
         * extension point.  If not found it uses the <code>IAdaptable</code>
         * mechanism.
         * @param part active part
         * @param selection active selection in part
         * @return The toggle breakpoints target, or <code>null</code> if not found.
         */
        private IToggleBreakpointsTarget getToggleBreakpointsTarget(IAdaptable adaptable) {
            if (adaptable != null) {
                IToggleBreakpointsTarget adapter = (IToggleBreakpointsTarget) 
                    adaptable.getAdapter(IToggleBreakpointsTarget.class);
                if (adapter == null) {
                    // attempt to force load adapter
                    IAdapterManager adapterManager = Platform.getAdapterManager();
                    if (adapterManager.hasAdapter(adaptable, IToggleBreakpointsTarget.class.getName())) {
                        adapter = (IToggleBreakpointsTarget) 
                            adapterManager.loadAdapter(adaptable, IToggleBreakpointsTarget.class.getName());
                    }
                }
                return adapter;
            }
            return null;
        }

        /**
         * Checks if there is an adaptable object for the given part and 
         * selection, and if there is, it checks whether an 
         * <code>IToggleBreakpointsTarget</code> can be obtained as an adapter.
         */
        public boolean isEnabled(IWorkbenchPart part, ISelection selection) {
            IAdaptable adaptable = getAdaptable(part, selection);
            return adaptable != null && canGetToggleBreakpointsTarget(adaptable);
        }
        
        /**
         * Not implemented use {@link #createDefaultToggleTarget(IWorkbenchPart, ISelection)}
         * instead.
         */
        public IToggleBreakpointsTarget createToggleTarget(String targetID) {
            return null;
        }
        
        /**
         * Returns a toggle target for the given part and selection, obtained 
         * through the adapter mechanism. 
         */
        public IToggleBreakpointsTarget createDefaultToggleTarget(IWorkbenchPart part, ISelection selection) {
            IAdaptable adaptable = getAdaptable(part, selection);
            return getToggleBreakpointsTarget(adaptable);
        }
        
        public Set getToggleTargets(IWorkbenchPart part, ISelection selection) {
            IAdaptable adaptable = getAdaptable(part, selection);
            if (canGetToggleBreakpointsTarget(adaptable)) {
                return DEFAULT_TOGGLE_TARGET_ID_SET;
            } 
            return Collections.EMPTY_SET;
        }

        public String getToggleTargetName(String targetID) {
            return ActionMessages.ToggleBreakpointsTargetManager_defaultToggleTarget_name;
        }

        public String getToggleTargetDescription(String targetID) {
            return ActionMessages.ToggleBreakpointsTargetManager_defaultToggleTarget_description;
        }
        
        public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) {
            return DEFAULT_TOGGLE_TARGET_ID;
        }
    }

    
    /**
     * Preference key for storing the preferred targets map.
     * @see {@link #storePreferredTargets()}
     * @see {@link #loadPreferredTargets()}
     */
    public static final String PREF_TARGETS = "preferredTargets"; //$NON-NLS-1$

    
    /**
     * There should only ever be once instance of this manager for the workbench.
     */
    private static ToggleBreakpointsTargetManager fgSingleton;

    public static ToggleBreakpointsTargetManager getDefault(){
        if (fgSingleton == null) fgSingleton = new ToggleBreakpointsTargetManager();
        return fgSingleton;
    }
    
    /**
     * Maps the IDs of toggle breakpoint targets to their instances.  The target
     * IDs must be unique.
     */
    private Map fKnownFactories;

    /**
     * Maps a Set of target id's to the one target id that is preferred.
     */
    private Map fPreferredTargets;
    
    /**
     * Maps the IDs of toggle targets to the factory that can create them.
     * There can currently only be one factory for a given toggle target.
     */
    private Map fFactoriesByTargetID = new HashMap();
    
    /**
     * List of listeners to changes in the preferred toggle targets list.
     */
    private ListenerList fChangedListners = new ListenerList();

    /**
     * Initializes the collection of known factories from extension point contributions.
     */
    private void initializeFactories() {
        fKnownFactories = new LinkedHashMap();
        fKnownFactories.put(DEFAULT_TOGGLE_TARGET_ID, new ToggleBreakpointsTargetAdapterFactory());
        IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_TOGGLE_BREAKPOINTS_TARGET_FACTORIES);
        IConfigurationElement[] elements = ep.getConfigurationElements();
        for (int i= 0; i < elements.length; i++) {
            String id = elements[i].getAttribute(IConfigurationElementConstants.ID); 
            if (id != null && id.length() != 0) {
                if (fKnownFactories.containsKey(id)) {
                    DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "org.eclipse.debug.ui.toggleBreakpointsTargetFactory extension failed to load breakpoint toggle target because the specified id is already registered.  Specified ID is: " + id, null)); //$NON-NLS-1$
                } else {
                    fKnownFactories.put(id, new ToggleTargetFactory(elements[i]));
                }
            } else {
                DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "org.eclipse.debug.ui.toggleBreakpointsTargetFactory extension failed to load breakpoint toggle target because the specified id is empty.", null)); //$NON-NLS-1$
            }
        }   
        
        // If there are any factories contributed through the extension point, 
        // set a system property for use in enabling actions.
        System.setProperty(IDebugUIConstants.SYS_PROP_BREAKPOINT_TOGGLE_FACTORIES_USED, 
        		fKnownFactories.size() > 1 ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
    }

    /**
     * Returns the set of IToggleBreakpointsTargetFactory objects (they will be
     * ToggleTargetFactory) that were contributed to the extension point and 
     * are enabled for the given part and selection (enabled if the factory 
     * does not have an enablement expression or if the enablement expression 
     * evaluates to true).
     * 
     * @param part active part
     * @param selection active selection in part
     * @return The factories enabled for the part and selection or an empty 
     * collection.
     */
    private Set getEnabledFactories(IWorkbenchPart part, ISelection selection) {
        if (fKnownFactories == null) initializeFactories();

        Set set = new LinkedHashSet();
        for (Iterator itr = fKnownFactories.keySet().iterator(); itr.hasNext(); ) {
            String id = (String)itr.next();
            IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fKnownFactories.get(id);
            if (factory instanceof ToggleTargetFactory && 
                ((ToggleTargetFactory)factory).isEnabled(part, selection)) {
                set.add(factory);
            } else if (factory instanceof ToggleBreakpointsTargetAdapterFactory && 
                ((ToggleBreakpointsTargetAdapterFactory)factory).isEnabled(part, selection)) {
                set.add(factory);
            } 
        }
        return set;
    }

    /**
     * Produces the set of IDs for all possible toggle targets that can be used for
     * the given part and selection.
     *  
     * @param factoriesToQuery The collection of factories to check
     * @param part active part
     * @param selection active selection in part
     * @return Set of toggle target IDs or an empty set
     */
    private Set getEnabledTargetIDs(Collection factoriesToQuery, IWorkbenchPart part, ISelection selection){
        Set idsForSelection = new LinkedHashSet();
        Iterator factoriesItr = factoriesToQuery.iterator();
        while (factoriesItr.hasNext()) {
            IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory) factoriesItr.next();
            Iterator targetIDsItr = factory.getToggleTargets(part, selection).iterator();
            while (targetIDsItr.hasNext()) {
                String targetID = (String) targetIDsItr.next();
                fFactoriesByTargetID.put(targetID, factory);
                idsForSelection.add(targetID);             
            }           
        }
        return idsForSelection;
    }

    /**
     * Returns the set of <code>String</code> IDs of toggle breakpoint targets, 
     * which are enabled for the given active part and selection.  The IDs can be used
     * to create the {@link IToggleBreakpointsTarget} instance.  
     * @param part active part
     * @param selection active selection in part
     * @return Set of toggle target IDs or an empty set
     */
    public Set getEnabledToggleBreakpointsTargetIDs(IWorkbenchPart part, ISelection selection) {
        return getEnabledTargetIDs(getEnabledFactories(part, selection), part, selection);
    }

    /**
     * Returns the ID of the calculated preferred toggle breakpoints target for the
     * given active part and selection.  The returned ID is chosen based on factory 
     * enablement, whether the target is a default one, and on user choice. 
     * @param part active part
     * @param selection active selection in part
     * @return The toggle target IDs or null if none.
     */
    public String getPreferredToggleBreakpointsTargetID(IWorkbenchPart part, ISelection selection) {
        Set factories = getEnabledFactories(part, selection);
        Set possibleIDs = getEnabledTargetIDs(factories, part, selection);
        return chooseToggleTargetIDInSet(possibleIDs, factories, part, selection);
    }

    /**
     * Given the ID of toggle breakpoint target, this method will try to find the factory
     * that creates it and return an instance of it.
     * 
     * @param ID The ID of the requested toggle breakpoint target.
     * @return The instantiated target or null
     */
    public IToggleBreakpointsTarget getToggleBreakpointsTarget(IWorkbenchPart part, ISelection selection) {
        String id = getPreferredToggleBreakpointsTargetID(part, selection);
        IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fFactoriesByTargetID.get(id);
        if (factory != null) {
            if (DEFAULT_TOGGLE_TARGET_ID.equals(id)) {
                return ((ToggleBreakpointsTargetAdapterFactory)factory).createDefaultToggleTarget(part, selection);
            } else {
                return factory.createToggleTarget(id);
            }
        }
        return null;
    }
    
    /**
     * Given the ID of a toggle breakpoints target, this method will try 
     * to find the factory that creates it and ask it for the name of it.
     * 
     * @param ID The ID of the requested toggle breakpoint target.
     * @return The name of the target.
     */
    public String getToggleBreakpointsTargetName(String id) {
        IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fFactoriesByTargetID.get(id);
        if (factory != null) {
            return factory.getToggleTargetName(id);
        }
        return null;
    }
    
    /**
     * Given the ID of a toggle breakpoints target, this method will try 
     * to find the factory that creates it and ask it for the description of it.
     * 
     * @param ID The ID of the requested toggle breakpoint target.
     * @return The description of the target or null.
     */
    public String getToggleBreakpointsTargetDescription(String id) {
        IToggleBreakpointsTargetFactory factory = (IToggleBreakpointsTargetFactory)fFactoriesByTargetID.get(id);
        if (factory != null) {
            return factory.getToggleTargetDescription(id);
        }
        return null;
    }

    /**
     * Adds the given listener to the list of listeners notified when the preferred
     * toggle breakpoints targets change.
     * @param listener The listener to add.
     */
    public void addChangedListener(IToggleBreakpointsTargetManagerListener listener) {
        fChangedListners.add(listener);
    }

    /**
     * Removes the given listener from the list of listeners notified when the preferred
     * toggle breakpoints targets change.
     * @param listener The listener to add.
     */
    public void removeChangedListener(IToggleBreakpointsTargetManagerListener listener) {
        fChangedListners.remove(listener);
    }

    /**
     * Stores the map of preferred target IDs to the preference store in the format:
     * 
     * Key1A,Key1B:Value1|Key2A,Key2B,Key2C:Value2| 
     * 
     * Where the sub keys (Key1A, Key1B, etc.) are the elements of the set used at the 
     * key in the mapping and the values are the associated String value in the mapping.
     */
    private void storePreferredTargets() {
        StringBuffer buffer= new StringBuffer();
        Iterator iter = fPreferredTargets.entrySet().iterator();
        while (iter.hasNext()) {
            Entry entry = (Entry) iter.next();
            Iterator setIter = ((Set)entry.getKey()).iterator();
            while (setIter.hasNext()) {
                String currentID = (String) setIter.next();
                buffer.append(currentID);
                buffer.append(',');
            }
            buffer.deleteCharAt(buffer.length()-1);
            buffer.append(':');
            buffer.append(entry.getValue());
            buffer.append('|');
        }
        DebugUIPlugin.getDefault().getPluginPreferences().setValue(PREF_TARGETS, buffer.toString());
    }

    /**
     * Loads the map of preferred target IDs from the preference store.
     * 
     * @see #storePreferredTargets()
     */
    private void loadPreferredTargets() {
        fPreferredTargets = new HashMap();
        String preferenceValue = DebugUIPlugin.getDefault().getPluginPreferences().getString(PREF_TARGETS);
        StringTokenizer entryTokenizer = new StringTokenizer(preferenceValue,"|"); //$NON-NLS-1$
        while (entryTokenizer.hasMoreTokens()){
            String token = entryTokenizer.nextToken();
            int valueStart = token.indexOf(':');
            StringTokenizer keyTokenizer = new StringTokenizer(token.substring(0,valueStart),","); //$NON-NLS-1$
            Set keys = new LinkedHashSet();
            while (keyTokenizer.hasMoreTokens()){
                keys.add(keyTokenizer.nextToken());
            }
            fPreferredTargets.put(keys, token.substring(valueStart+1));
        }
    }

    /**
     * Adds or updates the mapping to set which target ID is preferred for a certain
     * set of possible IDs.
     * 
     * @param possibleIDs The set of possible IDs
     * @param preferredID The preferred ID in the set.
     */
    public void setPreferredTarget(Set possibleIDs, String preferredID) {
        if (possibleIDs == null) return;

        if (fKnownFactories == null) initializeFactories();

        if (fPreferredTargets == null){
            loadPreferredTargets();
        }
        String currentKey = (String)fPreferredTargets.get(possibleIDs);
        if (currentKey == null || !currentKey.equals(preferredID)){
            fPreferredTargets.put(possibleIDs, preferredID);
            storePreferredTargets();
            firePreferredTargetsChanged();
        }        
    }
    
    /**
     * Returns the preferred pane ID from the given set if the mapping has been set.
     * 
     * @param possibleDetailsAreaIDs Set of possible pane IDs
     * @return The preferred ID or null
     */
    private String getUserPreferredTarget(Set possibleTargetIDs){
        if (fPreferredTargets == null){
            loadPreferredTargets();
        }
        return (String)fPreferredTargets.get(possibleTargetIDs);
    }

    /**
     * Given a set of possible detail pane IDs, this method will determine which pane is
     * preferred and should be used to display the selection.  This method chooses a pane
     * by storing previous choices and can be set using a context menu.
     * 
     * @param possiblePaneIDs The set of possible detail pane IDs
     * @return The preferred detail pane ID or null
     */
    private String chooseToggleTargetIDInSet(Set possibleTargetIDs, Collection enabledFactories, IWorkbenchPart part, ISelection selection){
        if (possibleTargetIDs == null || possibleTargetIDs.isEmpty()){
            return null;
        }
        
        String preferredID = getUserPreferredTarget(possibleTargetIDs);
        
        if (preferredID == null){
            // If there is no preferred pane already set, check the factories to see there is a default target
            Iterator factoryIterator = enabledFactories.iterator();
            while (preferredID == null && factoryIterator.hasNext()) {
                IToggleBreakpointsTargetFactory currentFactory = (IToggleBreakpointsTargetFactory) factoryIterator.next();
                preferredID = currentFactory.getDefaultToggleTarget(part, selection);
            }
            // If the factories don't have a default, just pick the first one.
            if (preferredID == null) {
                preferredID= (String)possibleTargetIDs.iterator().next();
            }
            setPreferredTarget(possibleTargetIDs, preferredID);
        }

        return preferredID;
    }

    /**
     * Notifies the change listeners that the preferred targets changed.
     */
    private void firePreferredTargetsChanged() {
        Object[] listeners = fChangedListners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
            ((IToggleBreakpointsTargetManagerListener)listeners[i]).preferredTargetsChanged();
        }
    }
    
}
