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

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;

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.resources.IMarker;
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.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
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.debug.ui.actions.IToggleBreakpointsTargetManager;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetManagerListener;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;

/**
 * The concrete implementation of the toggle breakpoints target manager
 * interface.
 *
 * @since 3.5
 */
public class ToggleBreakpointsTargetManager implements IToggleBreakpointsTargetManager {

    /**
     * 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<String> DEFAULT_TOGGLE_TARGET_ID_SET = new TreeSet<>();
    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;
        }

        /**
         * @return 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.
         * @param part The active part.
         * @param selection The current selection
         * @return whether the delegated target factory is enabled for 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 part the {@link IWorkbenchPart} context
         * @param selection the current selection in the part
         * @param exp the current expression
         * @return the result of evaluating the expression
         */
        private boolean evalEnablementExpression(IWorkbenchPart part, ISelection selection, Expression exp) {
            if (exp != null){
                IEvaluationContext context = DebugUIPlugin.createEvaluationContext(part);
				List<Object> debugContextList = getDebugContext(part).toList();
                context.addVariable(IConfigurationElementConstants.DEBUG_CONTEXT, debugContextList);

                if (selection instanceof IStructuredSelection) {
					List<Object> 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;
        }

        /**
		 * @return Returns an expression that represents the enablement logic
		 *         for the breakpoint 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
         * @param targetID ID to create toggle target for
         * @return The created toggle target, or null.
         */
        @Override
		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.
         * @param part The active part.
         * @param selection The current selection
         * @return Set of <code>String</code> IDs for possible toggle breakpoint
         * targets, possibly empty
         */
        @Override
		public Set<String> 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.
         * @param targetID toggle breakpoints target identifier
         * @return toggle target name
         */
        @Override
		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.
         * @param targetID toggle breakpoints target identifier
         * @return toggle target name or <code>null</code> if none
         */
        @Override
		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.
         * @param part The active part.
         * @param selection The current selection
         * @return a breakpoint toggle target identifier or <code>null</code>
         */
        @Override
		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 Object getSelectionElement(ISelection selection) {
            if (selection instanceof IStructuredSelection) {
                IStructuredSelection ss = (IStructuredSelection)selection;
                return ss.getFirstElement();
            }
            return null;
        }

        /**
         * Checks whether the given element is adaptable to the toggle breakpoints target.
         * This method does not force loading of the adapter.
         * @param adaptable Element to adapt.
         * @return returns true if element can be adapted.
         */
        private boolean canGetToggleBreakpointsTarget(Object adaptable) {
            if (adaptable != null) {
                IToggleBreakpointsTarget adapter = null;
                if (adaptable instanceof IAdaptable) {
                    adapter = ((IAdaptable)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 The workbench part in which toggle target is to be used
         * @param element The selection element to retrieve the toggle adapter from
         * @return The toggle breakpoints target, or <code>null</code> if not found.
         */
        private IToggleBreakpointsTarget getToggleBreakpointsTarget(IWorkbenchPart part, Object element) {
        	IToggleBreakpointsTarget target = null;
            if (element != null) {
                target = (IToggleBreakpointsTarget) DebugPlugin.getAdapter(element, IToggleBreakpointsTarget.class);
            }
            if (target == null) {
                target = (IToggleBreakpointsTarget) DebugPlugin.getAdapter(part, IToggleBreakpointsTarget.class);
            }
            return target;
        }

        /**
         * 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.
         * @param part The workbench part in which toggle target is to be used
         * @param selection The active selection to use with toggle target
         * @return Whether the adapter (default) toggle target is available.
         */
        public boolean isEnabled(IWorkbenchPart part, ISelection selection) {
            return canGetToggleBreakpointsTarget(getSelectionElement(selection)) || canGetToggleBreakpointsTarget(part);
        }

        /**
         * Not implemented use {@link #createDefaultToggleTarget(IWorkbenchPart, ISelection)}
         * instead.
         * @param targetID not used
         * @return always returns null
         */
        @Override
		public IToggleBreakpointsTarget createToggleTarget(String targetID) {
            return null;
        }

        /**
         * @param part The workbench part in which toggle target is to be used
         * @param selection The active selection to use with toggle target
         * @return Returns a toggle target for the given part and selection, obtained
         * through the adapter mechanism.
         */
        public IToggleBreakpointsTarget createDefaultToggleTarget(IWorkbenchPart part, ISelection selection) {
            return getToggleBreakpointsTarget(part, getSelectionElement(selection));
        }

        @Override
		public Set<String> getToggleTargets(IWorkbenchPart part, ISelection selection) {
            if (isEnabled(part, selection)) {
                return DEFAULT_TOGGLE_TARGET_ID_SET;
            }
            return Collections.EMPTY_SET;
        }

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

        @Override
		public String getToggleTargetDescription(String targetID) {
            return ActionMessages.ToggleBreakpointsTargetManager_defaultToggleTarget_description;
        }

        @Override
		public String getDefaultToggleTarget(IWorkbenchPart part, ISelection selection) {
            return DEFAULT_TOGGLE_TARGET_ID;
        }
    }


    /**
     * Preference key for storing the preferred targets map.
     * @see #storePreferredTargets()
     * @see #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<String, IToggleBreakpointsTargetFactory> fKnownFactories;

    /**
     * Maps a Set of target id's to the one target id that is preferred.
     */
	private Map<Set<String>, String> 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<String, IToggleBreakpointsTargetFactory> fFactoriesByTargetID = new HashMap<>();

    /**
     * List of listeners to changes in the preferred toggle targets list.
     */
	private ListenerList<IToggleBreakpointsTargetManagerListener> 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<IToggleBreakpointsTargetFactory> getEnabledFactories(IWorkbenchPart part, ISelection selection) {
        if (fKnownFactories == null) {
			initializeFactories();
		}
		Set<IToggleBreakpointsTargetFactory> set = new HashSet<>();
		for (Entry<String, IToggleBreakpointsTargetFactory> entry : fKnownFactories.entrySet()) {
			IToggleBreakpointsTargetFactory factory = entry.getValue();
            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<String> getEnabledTargetIDs(Set<IToggleBreakpointsTargetFactory> factoriesToQuery, IWorkbenchPart part, ISelection selection) {
		Set<String> idsForSelection = new TreeSet<>();
		for (IToggleBreakpointsTargetFactory factory : factoriesToQuery) {
			for(String targetID : factory.getToggleTargets(part, selection)) {
                fFactoriesByTargetID.put(targetID, factory);
                idsForSelection.add(targetID);
            }
        }
        return idsForSelection;
    }

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetManager#
	 * getEnabledToggleBreakpointsTargetIDs(org.eclipse.ui.IWorkbenchPart,
	 * org.eclipse.jface.viewers.ISelection)
	 */
    @Override
	public Set<String> getEnabledToggleBreakpointsTargetIDs(IWorkbenchPart part, ISelection selection) {
        return getEnabledTargetIDs(getEnabledFactories(part, selection), part, selection);
    }

    @Override
	public String getPreferredToggleBreakpointsTargetID(IWorkbenchPart part, ISelection selection) {
		Set<IToggleBreakpointsTargetFactory> factories = getEnabledFactories(part, selection);
		Set<String> possibleIDs = getEnabledTargetIDs(factories, part, selection);
        return chooseToggleTargetIDInSet(possibleIDs, part, selection);
    }

    @Override
	public IToggleBreakpointsTarget getToggleBreakpointsTarget(IWorkbenchPart part, ISelection selection) {
        String id = getPreferredToggleBreakpointsTargetID(part, selection);
        IToggleBreakpointsTargetFactory factory = 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;
    }

    @Override
	public String getToggleBreakpointsTargetName(String id) {
        IToggleBreakpointsTargetFactory factory = fFactoriesByTargetID.get(id);
        if (factory != null) {
            return factory.getToggleTargetName(id);
        }
        return null;
    }

    @Override
	public String getToggleBreakpointsTargetDescription(String id) {
        IToggleBreakpointsTargetFactory factory = fFactoriesByTargetID.get(id);
        if (factory != null) {
            return factory.getToggleTargetDescription(id);
        }
        return null;
    }

    @Override
	public void addChangedListener(IToggleBreakpointsTargetManagerListener listener) {
        fChangedListners.add(listener);
    }

    @Override
	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();
		for (Entry<Set<String>, String> entry : fPreferredTargets.entrySet()) {
			for (String currentID : entry.getKey()) {
                buffer.append(currentID);
                buffer.append(',');
            }
            buffer.deleteCharAt(buffer.length()-1);
            buffer.append(':');
            buffer.append(entry.getValue());
            buffer.append('|');
        }
        IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(DebugUIPlugin.getUniqueIdentifier());
        if(prefs != null) {
        	prefs.put(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 = Platform.getPreferencesService().getString(
        		DebugUIPlugin.getUniqueIdentifier(),
        		PREF_TARGETS,
        		null,
        		null);
        if(preferenceValue == null) {
        	return;
        }
        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<String> keys = new TreeSet<>();
            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<String> possibleIDs, String preferredID) {
        if (possibleIDs == null) {
			return;
		}

        if (fKnownFactories == null) {
			initializeFactories();
		}

        if (fPreferredTargets == null){
            loadPreferredTargets();
        }
        String currentKey = fPreferredTargets.get(possibleIDs);
        if (currentKey == null || !currentKey.equals(preferredID)){
            fPreferredTargets.put(possibleIDs, preferredID);
            storePreferredTargets();
            firePreferredTargetsChanged();
        }
    }

    /**
     * Returns the preferred toggle target ID from the given set if the mapping has been set.
     *
     * @param possibleTargetIDs The set of possible toggle target IDs
     * @return The preferred ID or null
     */
	private String getUserPreferredTarget(Set<String> possibleTargetIDs) {
        if (fPreferredTargets == null){
            loadPreferredTargets();
        }
        return fPreferredTargets.get(possibleTargetIDs);
    }

    /**
     * Given a set of possible toggle target IDs, this method will determine which target is
     * preferred and should be used to toggle breakpoints.  This method chooses a toggle target
     * by storing previous choices and can be set using a context menu.
     *
     * @param possibleTargetIDs The set of possible toggle target IDs
     * @param part The workbench part in which toggle target is to be used
     * @param selection The active selection to use with toggle target
     * @return The preferred toggle target ID or null
     */
	private String chooseToggleTargetIDInSet(Set<String> possibleTargetIDs, 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<String> possibleIDsIterator = possibleTargetIDs.iterator();
            while (preferredID == null && possibleIDsIterator.hasNext()) {
                IToggleBreakpointsTargetFactory factory = fFactoriesByTargetID.get(possibleIDsIterator.next());
                if (factory != null) {
                    preferredID = factory.getDefaultToggleTarget(part, selection);
                }
            }
            // If the factories don't have a default, just pick the first one.
            // Also make sure that the default is among the available toggle target
            // IDs (bug 352502).
            if (preferredID == null || !possibleTargetIDs.contains(preferredID)) {
                preferredID= possibleTargetIDs.iterator().next();
            }
            setPreferredTarget(possibleTargetIDs, preferredID);
        }

        return preferredID;
    }

    /**
     * Notifies the change listeners that the preferred targets changed.
     */
    private void firePreferredTargetsChanged() {
		for (IToggleBreakpointsTargetManagerListener iToggleBreakpointsTargetManagerListener : fChangedListners) {
			iToggleBreakpointsTargetManagerListener.preferredTargetsChanged();
        }
    }

    public IBreakpoint getBeakpointFromEditor(ITextEditor editor, IVerticalRulerInfo info) {
    	IDocumentProvider provider = editor.getDocumentProvider();
    	if(provider == null) {
    		return null;
    	}
    	IEditorInput input = editor.getEditorInput();
    	IAnnotationModel annotationModel = provider.getAnnotationModel(input);
		if (annotationModel != null) {
			IDocument document = provider.getDocument(input);
			Iterator<Annotation> iterator = annotationModel.getAnnotationIterator();
			while (iterator.hasNext()) {
				Annotation annot = iterator.next();
				if (annot instanceof SimpleMarkerAnnotation) {
					SimpleMarkerAnnotation markerAnnotation = (SimpleMarkerAnnotation) annot;
					IMarker marker = markerAnnotation.getMarker();
					try {
						if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
							Position position = annotationModel.getPosition(markerAnnotation);
							int line = document.getLineOfOffset(position.getOffset());
							if (line == info.getLineOfLastMouseButtonActivity()) {
								IBreakpoint breakpoint = DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
								if (breakpoint != null) {
									return breakpoint;
								}
							}
						}
					} catch (CoreException e) {
					} catch (BadLocationException e) {
					}
				}
			}
		}
    	return null;
    }
}
