Merge commit
authorEd Swartz <ed.swartz@nokia.com>
Fri, 04 Dec 2009 14:32:55 -0600
changeset 124 e120fb809ed2
parent 123 71e3840b8eca (current diff)
parent 122 d94b9ba55bed (diff)
child 125 bcbc185c1d01
Merge commit
cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointAttributeTranslator.java
cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslatorExtension.java
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointAttributeTranslator.java	Fri Dec 04 14:31:59 2009 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,561 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 Nokia 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:
- * 	Nokia - Initial API and implementation. Nov, 2009.
- *******************************************************************************/
-package org.eclipse.cdt.dsf.mi.service;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.cdt.debug.core.model.ICBreakpoint;
-import org.eclipse.cdt.debug.core.model.ICBreakpointExtension;
-import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
-import org.eclipse.cdt.debug.core.model.ICWatchpoint;
-import org.eclipse.cdt.debug.internal.core.breakpoints.BreakpointProblems;
-import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
-import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
-import org.eclipse.cdt.dsf.datamodel.DMContexts;
-import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator;
-import org.eclipse.cdt.dsf.debug.service.IBreakpointAttributeTranslatorExtension;
-import org.eclipse.cdt.dsf.debug.service.IDsfBreakpointExtension;
-import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
-import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator.BreakpointEventType;
-import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator.ITargetBreakpointInfo;
-import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
-import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
-import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
-import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
-import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
-import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
-import org.eclipse.cdt.dsf.service.DsfServicesTracker;
-import org.eclipse.cdt.dsf.service.DsfSession;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.model.IBreakpoint;
-
-public class MIBreakpointAttributeTranslator implements IBreakpointAttributeTranslatorExtension {
-
-    private final static String GDB_DEBUG_MODEL_ID = "org.eclipse.cdt.dsf.gdb"; //$NON-NLS-1$
-
-    // Extra breakpoint attributes
-    private static final String ATTR_DEBUGGER_PATH = GdbPlugin.PLUGIN_ID + ".debuggerPath";   //$NON-NLS-1$
-    private static final String ATTR_THREAD_FILTER = GdbPlugin.PLUGIN_ID + ".threadFilter";   //$NON-NLS-1$
-//    private static final String ATTR_THREAD_ID     = GdbPlugin.PLUGIN_ID + ".threadID";       //$NON-NLS-1$
-
-	private DsfServicesTracker	dsfServicesTracker;
-	private DsfSession			dsfSession;
-	private BreakpointsMediator	breakpointsMediator;
-	private String				debugModelId;
-
-	/**
-	 * Manage breakpoint problem markers. <br>
-	 * It's better be done by MIBreakpoints service so that it's accessible by
-	 * the MIBreakpoints service too. But to minimize change to MIBreakpoints in
-	 * this iteration, I just put it here..... 11/18/09
-	 */
-    private Map<ICBreakpoint, IMarker> fBreakpointMarkerProblems =
-        new HashMap<ICBreakpoint, IMarker>();
-
-	public MIBreakpointAttributeTranslator(DsfSession dsfSession, String debugModelId) {
-		super();
-		this.dsfSession = dsfSession;
-		this.debugModelId = debugModelId;
-		
-		dsfServicesTracker = new DsfServicesTracker(GdbPlugin.getDefault().getBundle().getBundleContext(), dsfSession.getId());
-	}
-
-	public boolean canUpdateAttributes(IBreakpointDMContext bp, Map<String, Object> delta) {
-		/*
-		 * This method decides whether we need to re-install the breakpoint
-		 * based on the attributes change (refer to caller in
-		 * BreakpointsMediator).
-		 */         
-        // Check if there is any modified attribute
-        if (delta == null || delta.size() == 0)
-            return true;
-
-        // Check the "critical" attributes
-        if (delta.containsKey(ATTR_DEBUGGER_PATH)            // File name
-        ||  delta.containsKey(MIBreakpoints.LINE_NUMBER)     // Line number
-        ||  delta.containsKey(MIBreakpoints.FUNCTION)        // Function name
-        ||  delta.containsKey(MIBreakpoints.ADDRESS)         // Absolute address
-        ||  delta.containsKey(ATTR_THREAD_FILTER)            // Thread ID
-        ||  delta.containsKey(MIBreakpoints.EXPRESSION)      // Watchpoint expression
-        ||  delta.containsKey(MIBreakpoints.READ)            // Watchpoint type
-        ||  delta.containsKey(MIBreakpoints.WRITE)) {        // Watchpoint type
-            return false;
-        }
-
-        // for other attrs (ICBreakpoint.INSTALL_COUNT, ICBreakpoint.IGNORE_COUNT,
-        // ICBreakpoint.CONDITION, etc), we can update them.
-        return true;
-	}
-
-	public void dispose() {
-		if (dsfServicesTracker != null)
-			dsfServicesTracker.dispose();
-		dsfSession = null;
-		
-		clearBreakpointProblemMarkers();
-	}
-
-	public List<Map<String, Object>> getBreakpointAttributes(IBreakpoint bp, boolean bpManagerEnabled)
-			throws CoreException {
-		// deprecated
-		List<Map<String, Object>> retVal = new ArrayList<Map<String, Object>>();
-		return retVal;
-	}
-
-	public void initialize(BreakpointsMediator mediator) {
-		breakpointsMediator = mediator;
-	}
-
-	public boolean supportsBreakpoint(IBreakpoint bp) {
-        if (bp instanceof ICBreakpoint && bp.getModelIdentifier().equals(debugModelId)) {
-            IMarker marker = bp.getMarker();
-            if (marker != null) {
-                return true;
-            }
-        }
-        return false;
-	}
-
-	public void updateBreakpointStatus(IBreakpoint bp) {
-		// obsolet, do nothing.
-	}
-
-	public void updateBreakpointsStatus(Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> bpsInfo,
-			BreakpointEventType eventType) {
-		for (IBreakpoint bp : bpsInfo.keySet()) {
-			if (! (bp instanceof ICBreakpoint))	// not C breakpoints, bail out.
-				return;
-			
-			final ICBreakpoint icbp = (ICBreakpoint) bp;
-
-			Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> targetBpPerContext = bpsInfo.get(bp);
-			
-			switch (eventType) {
-			case ADDED: {
-				int installCountTotal = 0;
-				StringBuffer errMsg = new StringBuffer();
-				for (ITargetBreakpointInfo[] tbpInfos : targetBpPerContext.values()) {
-					// For each BpTargetDMContext, we increment the installCount for each
-					// target BP that has been successfully installed.
-					int installCountPerContext = 0;
-					for (ITargetBreakpointInfo tbp : tbpInfos) {
-						if (tbp.getTargetBreakpoint() != null)
-							installCountPerContext++;
-						else // failure in installation
-							errMsg.append(tbp.getStatus().getMessage()).append('\n');
-					}
-					installCountTotal += installCountPerContext;
-				}
-
-				for (int i=0; i < installCountTotal; i++)
-					try {
-						// this will eventually carried out in a workspace runnable.
-						icbp.incrementInstallCount();
-					} catch (CoreException e) {
-						GdbPlugin.getDefault().getLog().log(e.getStatus());
-					}
-				
-				if (errMsg.length() > 0)
-					addBreakpointProblemMarker(icbp, errMsg.toString(), IMarker.SEVERITY_WARNING);
-				else // no error, clean message if any.
-					removeBreakpointProblemMarker(icbp);
-				
-				break;
-				}
-			case MODIFIED:
-				break;
-
-			case REMOVED: {
-				int removeCountTotal = 0;
-				for (ITargetBreakpointInfo[] tbpInfos : targetBpPerContext.values()) {
-					// For each BpTargetDMContext, we decrement the installCount for each
-					// target BP that we tried to remove, even if the removal failed. That's
-					// because I've not seen a way to tell platform that removal fails 
-					// and the BP should be kept in UI.
-					removeCountTotal += tbpInfos.length;
-				}
-
-				for (int i=0; i < removeCountTotal; i++)
-					try {
-						if (icbp.isRegistered())	// not deleted in UI
-							icbp.decrementInstallCount();
-					} catch (CoreException e) {
-						GdbPlugin.getDefault().getLog().log(e.getStatus());
-					}
-				break;
-				}
-			}
-		}
-	}
-
-	public Map<String, Object> convertAttributes(Map<String, Object> platformAttrs) {
-		Map<String, Object> targetAttrs = new HashMap<String, Object>();
-
-		if (platformAttrs.containsKey(MIBreakpoints.BREAKPOINT_TYPE))
-			targetAttrs.put(MIBreakpoints.BREAKPOINT_TYPE,      platformAttrs.get(MIBreakpoints.BREAKPOINT_TYPE));
-        	
-		if (platformAttrs.containsKey(ICWatchpoint.EXPRESSION))
-			targetAttrs.put(MIBreakpoints.EXPRESSION,      platformAttrs.get(ICWatchpoint.EXPRESSION));
-		if (platformAttrs.containsKey(ICWatchpoint.READ))
-			targetAttrs.put(MIBreakpoints.READ,            platformAttrs.get(ICWatchpoint.READ));
-		if (platformAttrs.containsKey(ICWatchpoint.WRITE))
-			targetAttrs.put(MIBreakpoints.WRITE,           platformAttrs.get(ICWatchpoint.WRITE));
-
-		if (platformAttrs.containsKey(ICBreakpoint.SOURCE_HANDLE))
-			targetAttrs.put(MIBreakpoints.FILE_NAME,       platformAttrs.get(ICBreakpoint.SOURCE_HANDLE));
-
-		if (platformAttrs.containsKey(IMarker.LINE_NUMBER))
-			targetAttrs.put(MIBreakpoints.LINE_NUMBER,     platformAttrs.get(IMarker.LINE_NUMBER));
-		if (platformAttrs.containsKey(ICLineBreakpoint.FUNCTION))
-			targetAttrs.put(MIBreakpoints.FUNCTION,        platformAttrs.get(ICLineBreakpoint.FUNCTION));
-		if (platformAttrs.containsKey(ICLineBreakpoint.ADDRESS))
-			targetAttrs.put(MIBreakpoints.ADDRESS,         platformAttrs.get(ICLineBreakpoint.ADDRESS));
-		
-		if (platformAttrs.containsKey(ICBreakpoint.CONDITION))
-			targetAttrs.put(MIBreakpoints.CONDITION,           platformAttrs.get(ICBreakpoint.CONDITION));
-		if (platformAttrs.containsKey(ICBreakpoint.IGNORE_COUNT))
-			targetAttrs.put(MIBreakpoints.IGNORE_COUNT,        platformAttrs.get(ICBreakpoint.IGNORE_COUNT));
-		if (platformAttrs.containsKey(ICBreakpoint.ENABLED))
-			targetAttrs.put(MIBreakpoints.IS_ENABLED,          platformAttrs.get(ICBreakpoint.ENABLED));
-		
-		return targetAttrs;
-	}
-
-    @SuppressWarnings("unchecked")
-	public void resolveBreakpoint(IBreakpointsTargetDMContext context, IBreakpoint breakpoint, 
-    		Map<String, Object> bpAttributes, final DataRequestMonitor<List<Map<String, Object>>> drm) {
-		
-    	assert dsfSession.getExecutor().isInExecutorThread();
-    	
-    	// Create a copy as we don't want to change "bpAttributes".
-		final Map<String, Object>	targetBPAttrBase = new HashMap<String, Object>(bpAttributes);
-		
-		final Set<String> threads = (Set<String>) targetBPAttrBase.get(ATTR_THREAD_FILTER);
-
-		final List<Map<String, Object>>	targetBPList = new ArrayList<Map<String, Object>>();
-
-		// get debugger path (compilation-path) for source file, if any.
-		determineDebuggerPath(context, targetBPAttrBase, new RequestMonitor(dsfSession.getExecutor(), drm){
-			@Override
-			protected void handleSuccess() {
-				// Create attribute list for each thread
-				for (String thread : threads) {
-					Map<String, Object> targetBP = new HashMap<String, Object>(targetBPAttrBase);
-					targetBP.put(MIBreakpointDMData.THREAD_ID, thread);
-					targetBPList.add(targetBP);
-				}
-
-				drm.setData(targetBPList);
-				drm.done();
-			}});
-	}
-
-    /**
-     * determineDebuggerPath
-     * 
-     * Adds the path to the source file to the set of attributes
-     * (for the debugger).
-     * 
-     * @param dmc
-     * @param targetAttrs
-     * @param rm
-     */
-    private void determineDebuggerPath(IBreakpointsTargetDMContext dmc,
-            final Map<String, Object> targetAttrs, final RequestMonitor rm)
-    {
-        String hostPath = (String) targetAttrs.get(MIBreakpoints.FILE_NAME);
-
-        if (hostPath != null) {
-            ISourceLookup sourceService   = dsfServicesTracker.getService(ISourceLookup.class);
-
-            ISourceLookupDMContext srcDmc = DMContexts.getAncestorOfType(dmc, ISourceLookupDMContext.class);
-            if (srcDmc != null) {
-                sourceService.getDebuggerPath(srcDmc, hostPath,
-                    new DataRequestMonitor<String>(dsfSession.getExecutor(), rm) {
-                        @Override
-                        protected void handleSuccess() {
-                            targetAttrs.put(ATTR_DEBUGGER_PATH, adjustDebuggerPath(getData()));
-                            rm.done();
-                        }
-                    });
-            } else {
-                // Source lookup not available for given context, use the host
-                // path for the debugger path.
-                targetAttrs.put(ATTR_DEBUGGER_PATH, adjustDebuggerPath(hostPath));
-                rm.done();
-            }
-        } else {
-            // Some types of breakpoints do not require a path
-            // (e.g. watchpoints)
-            rm.done();
-        }
-    }
-
-    /**
-     * See bug232415
-     * 
-     * @param path	the absolute path to the source file
-     * @return
-     */
-    private String adjustDebuggerPath(String path) {
-    	String result = path;
-    	// Make it MinGW-specific
-    	if (Platform.getOS().startsWith("win")) { //$NON-NLS-1$
-        	if (!path.startsWith("/")) { //$NON-NLS-1$
-        		result = path.substring(path.lastIndexOf('\\') + 1);
-        	}
-    	}
-    	return result;
-    }
-
-	/**
-	 * Get the list of threads from the platform breakpoint attributes
-	 * 
-	 * @param context
-	 *            if the context is not null, only get threads that are children
-	 *            of this context. otherwise get all threads.
-	 * @param breakpoint
-	 * @return
-	 */
-    private Set<String> extractThreads(IBreakpointsTargetDMContext context, ICBreakpoint breakpoint) {
-        Set<String> results = new HashSet<String>();
-
-        // Find the ancestor
-        List<IExecutionDMContext[]> threads = new ArrayList<IExecutionDMContext[]>(1);
-
-        try {
-            // Retrieve the targets
-            IDsfBreakpointExtension filterExtension = getFilterExtension(breakpoint);
-            IContainerDMContext[] targets = filterExtension.getTargetFilters();
-
-            // If no target is present, breakpoint applies to all.
-            if (targets.length == 0) {
-                results.add("0"); //$NON-NLS-1$    
-                return results;
-            }
-
-            // Extract the thread IDs (if there is none, we are covered)
-            for (IContainerDMContext ctxt : targets) {
-                if (context == null || 
-                	DMContexts.isAncestorOf(ctxt, context)) {
-                    threads.add(filterExtension.getThreadFilters(ctxt));
-                }
-            }
-        } catch (CoreException e1) {
-        }
-
-        if (supportsThreads(breakpoint)) {
-            for (IExecutionDMContext[] targetThreads : threads) {
-                if (targetThreads != null) {
-                    for (IExecutionDMContext thread : targetThreads) {
-                        if (thread instanceof IMIExecutionDMContext) {
-                        	IMIExecutionDMContext dmc = (IMIExecutionDMContext) thread;
-                            results.add(((Integer) dmc.getThreadId()).toString());
-                        }
-                    }
-                } else {
-                    results.add("0"); //$NON-NLS-1$    
-                    break;
-                }
-            }
-        } else {
-            results.add("0"); //$NON-NLS-1$
-        }
-
-        return results;
-    }
-
-    /**
-     * Indicates if the back-end supports multiple threads for
-     * this type of breakpoint
-     * 
-     * @param breakpoint
-     */
-    protected boolean supportsThreads(ICBreakpoint breakpoint) {
-
-        return !(breakpoint instanceof ICWatchpoint);
-    }
-
-    /**
-     * @param bp
-     * @return
-     * @throws CoreException
-     */
-    private IDsfBreakpointExtension getFilterExtension(ICBreakpoint bp) throws CoreException {
-        return (IDsfBreakpointExtension) bp.getExtension(GDB_DEBUG_MODEL_ID, ICBreakpointExtension.class);
-    }
-
-	public Map<String, Object> getAllBreakpointAttributes(IBreakpoint breakpoint, boolean bpManagerEnabled) throws CoreException {
-
-		assert ! dsfSession.getExecutor().isInExecutorThread();
-
-		// Check that the marker exists and retrieve its attributes.
-		// Due to accepted race conditions, the breakpoint marker may become
-		// null while this method is being invoked. In this case throw an exception
-		// and let the caller handle it.
-		IMarker marker = breakpoint.getMarker();
-		if (marker == null || !marker.exists()) {
-			throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
-					"Breakpoint marker does not exist", null));
-		}
-		
-		// Suppress cast warning: platform is still on Java 1.3
-		@SuppressWarnings("unchecked")
-		Map<String, Object> attributes = marker.getAttributes();
-
-		Map<String, Object>	targetAttrs = convertAttributes(attributes);
-
-		// Determine breakpoint type.
-        if (breakpoint instanceof ICWatchpoint)
-            targetAttrs.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.WATCHPOINT);
-        else if (breakpoint instanceof ICLineBreakpoint)
-            targetAttrs.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
-        else {
-	    	// catchpoint?
-	    }
-        	
-		// Adjust for "skip-all"
-		if (!bpManagerEnabled) {
-		    targetAttrs.put(MIBreakpoints.IS_ENABLED, false);
-		}
-
-		Set<String> threads = extractThreads(null, (ICBreakpoint) breakpoint);
-        targetAttrs.put(ATTR_THREAD_FILTER, threads);
-        
-        return targetAttrs;
-	}
-
-	public boolean canUpdateAttributes(IBreakpoint bp, IBreakpointsTargetDMContext context, Map<String, Object> attrDelta) {
-		boolean yesWeCan;
-		
-		if (attrDelta.containsKey(MIBreakpoints.IS_ENABLED) && bp != null) {
-			// GDB special: 
-			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=261082
-			//
-			Map<String, Object> delta = new HashMap<String, Object>(attrDelta);
-			
-			delta.remove(MIBreakpoints.IS_ENABLED);
-			
-			yesWeCan = canUpdateAttributes(null, delta);
-			
-			if (yesWeCan) {
-				// other attribute change indicates we can. Now check the ENABLE.
-				// if the breakpoint is already installed in the "context" (a process), 
-				// we can. Otherwise no.
-				ITargetBreakpointInfo[] targetBPs = breakpointsMediator.getTargetBreakpoints(context, bp);
-				yesWeCan = targetBPs != null && targetBPs.length > 0;
-			}
-		}
-		else 
-			yesWeCan = canUpdateAttributes(null, attrDelta);
-		
-		return yesWeCan;
-	}
-
-    private void addBreakpointProblemMarker(final ICBreakpoint breakpoint, final String description, final int severity) {
-
-        new Job("Add Breakpoint Problem Marker") { //$NON-NLS-1$
-        	{setSystem(true); };
-        	
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                
-                if (breakpoint instanceof ICLineBreakpoint) {
-                	// If we have already have a problem marker on this breakpoint
-                	// we should remove it first.
-                    IMarker marker = fBreakpointMarkerProblems.remove(breakpoint);
-                    if (marker != null) {
-                        try {
-                            marker.delete();
-                        } catch (CoreException e) {
-                        }
-                	}
-
-                    ICLineBreakpoint lineBreakpoint = (ICLineBreakpoint) breakpoint;
-                    try {
-                        // Locate the workspace resource via the breakpoint marker
-                        IMarker breakpoint_marker = lineBreakpoint.getMarker();
-                        IResource resource = breakpoint_marker.getResource();
-
-                        // Add a problem marker to the resource
-                        IMarker problem_marker = resource.createMarker(BreakpointProblems.BREAKPOINT_PROBLEM_MARKER_ID);
-                        int line_number = lineBreakpoint.getLineNumber();
-                        problem_marker.setAttribute(IMarker.LOCATION,    String.valueOf(line_number));
-                        problem_marker.setAttribute(IMarker.MESSAGE,     description);
-                        problem_marker.setAttribute(IMarker.SEVERITY,    severity);
-                        problem_marker.setAttribute(IMarker.LINE_NUMBER, line_number);
-
-                        // And save the baby
-                        fBreakpointMarkerProblems.put(breakpoint, problem_marker);
-                    } catch (CoreException e) {
-                    }
-                }
-                return Status.OK_STATUS;
-            }
-        }.schedule();
-    }
-
-    private void removeBreakpointProblemMarker(final ICBreakpoint breakpoint) {
-
-        new Job("Remove Breakpoint Problem Marker") { //$NON-NLS-1$
-        	{setSystem(true); };
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                
-                IMarker marker = fBreakpointMarkerProblems.remove(breakpoint);
-                if (marker != null) {
-                    try {
-                        marker.delete();
-                    } catch (CoreException e) {
-                    }
-                }
-
-                return Status.OK_STATUS;
-            }
-        }.schedule();
-    }
-
-    /**
-     */
-    private void clearBreakpointProblemMarkers()
-    {
-        new Job("Clear Breakpoint problem markers") { //$NON-NLS-1$
-        	{ setSystem(true); };
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-                for (IMarker marker : fBreakpointMarkerProblems.values()) {
-                	if (marker != null) {
-                		try {
-							marker.delete();
-						} catch (CoreException e) {
-						}
-                	}
-                }
-                fBreakpointMarkerProblems.clear();
-                return Status.OK_STATUS;
-            }
-        }.schedule();
-    }
-}
- 
\ No newline at end of file
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java	Fri Dec 04 14:31:59 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java	Fri Dec 04 14:32:55 2009 -0600
@@ -15,8 +15,6 @@
 import java.util.Hashtable;
 import java.util.Map;
 
-import org.eclipse.cdt.debug.core.CDebugCorePlugin;
-import org.eclipse.cdt.debug.core.model.ICBreakpoint;
 import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
 import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
 import org.eclipse.cdt.dsf.concurrent.Immutable;
@@ -29,8 +27,6 @@
 import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
 import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
 import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
-import org.eclipse.cdt.dsf.mi.service.MIRunControl.SuspendedEvent;
-import org.eclipse.cdt.dsf.mi.service.breakpoint.actions.BreakpointActionAdapter;
 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter;
 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakCondition;
 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakDelete;
@@ -39,9 +35,7 @@
 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert;
 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakList;
 import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakWatch;
-import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointHitEvent;
 import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointScopeEvent;
-import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointTriggerEvent;
 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakListInfo;
 import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
@@ -49,11 +43,8 @@
 import org.eclipse.cdt.dsf.service.AbstractDsfService;
 import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
 import org.eclipse.cdt.dsf.service.DsfSession;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -290,53 +281,6 @@
     public void eventDispatched(ICommandControlShutdownDMEvent e) {
     }
 
-	@DsfServiceEventHandler 
-    public void eventDispatched(SuspendedEvent e) {
-
-		if (e.getMIEvent() instanceof MIBreakpointHitEvent) {
-			MIBreakpointHitEvent evt = (MIBreakpointHitEvent) e.getMIEvent();
-	        performBreakpointAction(evt.getDMContext(), evt.getNumber());
-	        return;
-		}
-
-		if (e.getMIEvent() instanceof MIWatchpointTriggerEvent) {
-			MIWatchpointTriggerEvent evt = (MIWatchpointTriggerEvent) e.getMIEvent();
-	        performBreakpointAction(evt.getDMContext(), evt.getNumber());
-	        return;
-		}
-	}
-
-    private void performBreakpointAction(final IDMContext context, int number) {
-        // Identify the platform breakpoint
-        final ICBreakpoint breakpoint = findPlatformBreakpoint(context, number);
-
-        // Perform the actions asynchronously (otherwise we can have a deadlock...)
-        new Job("Breakpoint action") { //$NON-NLS-1$
-            { setSystem(true); }
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-            	CDebugCorePlugin.getDefault().getBreakpointActionManager().executeActions(breakpoint, new BreakpointActionAdapter(getExecutor(), getServicesTracker(), context));
-                return Status.OK_STATUS;
-            };
-        }.schedule();
-    }
-
-    // Helper function to locate the platform breakpoint corresponding
-    // to the target breakpoint/watchpoint that was just hit
-
-    // FIXME: (Bug228703) Need a way to identify the correct context where the BP was hit
-    private ICBreakpoint findPlatformBreakpoint(IDMContext context, int targetBreakpointID) {
-    	// Hmm, the service has no tracking of MIBreakpointDMContext. So this workaround.
-    	IBreakpointsTargetDMContext btDMC = DMContexts.getAncestorOfType(context, IBreakpointsTargetDMContext.class);
-    	assert btDMC != null;
-    	IBreakpointDMContext dmc = new MIBreakpointDMContext(MIBreakpoints.this, new IDMContext[] { btDMC }, targetBreakpointID);
-
-		MIBreakpointsManager bpMediator = getServicesTracker().getService(MIBreakpointsManager.class);
-		ICBreakpoint cdtBP = (ICBreakpoint)bpMediator.getPlatformBreakpoint(btDMC, dmc);
-    	
-        return cdtBP;
-    }
-    
 	///////////////////////////////////////////////////////////////////////////
 	// IBreakpoints interface
 	///////////////////////////////////////////////////////////////////////////
@@ -819,7 +763,7 @@
 		// Retrieve the breakpoint parameters
 		// At this point, we know their are OK so there is no need to re-validate
 		MIBreakpointDMContext breakpointCtx = (MIBreakpointDMContext) dmc;
-        final IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class);
+        IBreakpointsTargetDMContext context = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class);
 		final Map<Integer, MIBreakpointDMData> contextBreakpoints = fBreakpoints.get(context);
 		final int reference = breakpointCtx.getReference();
 		MIBreakpointDMData breakpoint = contextBreakpoints.get(reference);
@@ -838,22 +782,11 @@
         // Determine if the breakpoint condition changed
 		String conditionAttribute = CONDITION;
 		if (properties.containsKey(conditionAttribute)) {
-			final String oldValue = breakpoint.getCondition();
+			String oldValue = breakpoint.getCondition();
 			String newValue = (String) properties.get(conditionAttribute);
 			if (newValue == null) newValue = NULL_STRING;
 	        if (!oldValue.equals(newValue)) {
-	        	changeCondition(context, reference, newValue, new RequestMonitor(getExecutor(), countingRm){
-
-					@Override
-					protected void handleError() {
-						// Failed to change the condition, restore the old condition.
-						// See comment in changeCondition() for more.
-						MIBreakpointsManager bpMediator = getServicesTracker().getService(MIBreakpointsManager.class);
-						final ICBreakpoint cdtBP = (ICBreakpoint)bpMediator.getPlatformBreakpoint(context, dmc);
-						rollbackCondition(cdtBP, oldValue);
-
-						countingRm.done();
-					}});
+	        	changeCondition(context, reference, newValue, countingRm);
 	        	numberOfChanges++;
 	        }
 			properties.remove(conditionAttribute);
@@ -892,26 +825,6 @@
         countingRm.setDoneCount(numberOfChanges);
 	}
 
-	private void rollbackCondition(final ICBreakpoint cdtBP, final String oldValue) {
-		if (cdtBP == null)
-			return;
-		
-		new Job("rollback breakpont condition") { //$NON-NLS-1$
-			{ setSystem(true); }
-			@Override
-			protected IStatus run(IProgressMonitor monitor) {
-				try {
-					if (oldValue != null)
-						cdtBP.setCondition(oldValue);
-					else
-						cdtBP.setCondition(NULL_STRING);
-				} catch (CoreException e) {
-					// ignore
-				}
-				return Status.OK_STATUS;
-			}}.schedule(); 
-	}
-
 	/**
 	 * Update the breakpoint condition
 	 * 
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java	Fri Dec 04 14:31:59 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java	Fri Dec 04 14:32:55 2009 -0600
@@ -15,8 +15,74 @@
 
 package org.eclipse.cdt.dsf.mi.service;
 
-import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.core.breakpointactions.BreakpointActionManager;
+import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
+import org.eclipse.cdt.debug.core.model.ICBreakpoint;
+import org.eclipse.cdt.debug.core.model.ICBreakpointExtension;
+import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
+import org.eclipse.cdt.debug.core.model.ICWatchpoint;
+import org.eclipse.cdt.debug.internal.core.breakpoints.BreakpointProblems;
+import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
+import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
+import org.eclipse.cdt.dsf.datamodel.DMContexts;
+import org.eclipse.cdt.dsf.datamodel.IDMContext;
+import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
+import org.eclipse.cdt.dsf.debug.service.IDsfBreakpointExtension;
+import org.eclipse.cdt.dsf.debug.service.IRunControl;
+import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
+import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
+import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
+import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
+import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
+import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
+import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.BreakpointAddedEvent;
+import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.BreakpointRemovedEvent;
+import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.BreakpointUpdatedEvent;
+import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.MIBreakpointDMContext;
+import org.eclipse.cdt.dsf.mi.service.MIRunControl.SuspendedEvent;
+import org.eclipse.cdt.dsf.mi.service.breakpoint.actions.BreakpointActionAdapter;
+import org.eclipse.cdt.dsf.mi.service.command.events.MIBreakpointHitEvent;
+import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointScopeEvent;
+import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointTriggerEvent;
+import org.eclipse.cdt.dsf.service.AbstractDsfService;
+import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
 import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.MultiRule;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointListener;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.IBreakpointManagerListener;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.osgi.framework.BundleContext;
 
 /**
  * Breakpoint service interface.  The breakpoint service tracks CDT breakpoint
@@ -24,8 +90,107 @@
  * 
  * It relies on MIBreakpoints for the actual back-end interface.
  */
-public class MIBreakpointsManager extends BreakpointsMediator
+public class MIBreakpointsManager extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener
 {
+    // Note: Find a way to import this (careful of circular dependencies)
+    public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.cdt.dsf.gdb"; //$NON-NLS-1$
+
+    // Extra breakpoint attributes
+    private static final String ATTR_DEBUGGER_PATH = GdbPlugin.PLUGIN_ID + ".debuggerPath";   //$NON-NLS-1$
+    private static final String ATTR_THREAD_FILTER = GdbPlugin.PLUGIN_ID + ".threadFilter";   //$NON-NLS-1$
+    private static final String ATTR_THREAD_ID     = GdbPlugin.PLUGIN_ID + ".threadID";       //$NON-NLS-1$
+
+    // Services
+    ICommandControl    fConnection;
+    IRunControl        fRunControl;
+    ISourceLookup      fSourceLookup;
+    IBreakpoints       fBreakpoints;
+    IBreakpointManager fBreakpointManager;  // Platform breakpoint manager (not this!)
+    BreakpointActionManager fBreakpointActionManager;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Breakpoints tracking
+    ///////////////////////////////////////////////////////////////////////////
+
+    private String fDebugModelId;
+    
+    // Holds the set of platform breakpoints with their corresponding back-end
+    // breakpoint attributes, per context (i.e. each platform breakpoint is
+    // replicated for each execution context).
+    // - Context entry added/removed on start/stopTrackingBreakpoints()
+    // - Augmented on breakpointAdded()
+    // - Modified on breakpointChanged()
+    // - Diminished on breakpointRemoved()
+    private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Map<String, Object>>> fPlatformBPs =
+        new HashMap<IBreakpointsTargetDMContext, Map<ICBreakpoint, Map<String, Object>>>();
+
+    // Holds the set of target breakpoints, per execution context, and their
+    // mapping to the corresponding platform breakpoint. In a given execution
+    // context there can only be one platform breakpoint per target breakpoint.
+    // Acts as a mapping from target (low-level) BP to the corresponding platform
+    // (high-level) BP.
+    // Updated when:
+    // - We start/stop tracking an execution context
+    // - A platform breakpoint is added/removed
+    // - A thread filter is applied/removed
+    private Map<IBreakpointsTargetDMContext, Map<IBreakpointDMContext, ICBreakpoint>> fTargetBPs =
+        new HashMap<IBreakpointsTargetDMContext, Map<IBreakpointDMContext, ICBreakpoint>>();
+
+    // Holds the mapping from platform breakpoint to the corresponding target
+    // breakpoint(s), per context. There can be multiple back-end BPs for a
+    // single platform BP in the case of [1] multiple target contexts, and/or
+    // [2] thread filtering.
+    // Updated when:
+    // - We start/stop tracking an execution context
+    // - A platform breakpoint is added/removed
+    // - A thread filter is applied/removed
+    private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Vector<IBreakpointDMContext>>> fBreakpointIDs =
+        new HashMap<IBreakpointsTargetDMContext, Map<ICBreakpoint, Vector<IBreakpointDMContext>>>();
+
+    // Holds the mapping from platform breakpoint to the corresponding target
+    // breakpoint threads, per context.
+    // Updated when:
+    // - We start/stop tracking an execution context
+    // - A platform breakpoint is added/removed
+    // - A thread filter is applied/removed
+    private Map<IBreakpointsTargetDMContext, Map<ICBreakpoint, Set<String>>> fBreakpointThreads =
+        new HashMap<IBreakpointsTargetDMContext, Map<ICBreakpoint, Set<String>>>();
+
+    // Due to the very asynchronous nature of DSF, a new breakpoint request can
+    // pop up at any time before an ongoing one is completed. The following set
+    // is used to store requests until the ongoing operation completes.
+    private Set<IBreakpoint> fPendingRequests    = new HashSet<IBreakpoint>();
+    private Set<IBreakpoint> fPendingBreakpoints = new HashSet<IBreakpoint>();
+
+    private Map<ICBreakpoint, IMarker> fBreakpointMarkerProblems =
+        new HashMap<ICBreakpoint, IMarker>();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // String constants
+    ///////////////////////////////////////////////////////////////////////////
+
+    private static final String NULL_STRING = ""; //$NON-NLS-1$
+
+    static final String CONTEXT_ALREADY_INITIALIZED  = "Context already initialized";  //$NON-NLS-1$
+    static final String INVALID_CONTEXT_TYPE         = "Invalid context type";         //$NON-NLS-1$
+    static final String INVALID_CONTEXT              = "Invalid context";              //$NON-NLS-1$
+
+    static final String UNABLE_TO_READ_BREAKPOINT    = "Unable to read initial breakpoint attributes"; //$NON-NLS-1$
+    static final String BREAKPOINT_NOT_INSTALLED     = "Breakpoints not installed for given context";  //$NON-NLS-1$
+    static final String BREAKPOINT_ALREADY_INSTALLED = "Breakpoint already installed"; //$NON-NLS-1$
+    static final String BREAKPOINT_ALREADY_REMOVED   = "Breakpoint already removed";   //$NON-NLS-1$
+
+    static final String INVALID_BREAKPOINT           = "Invalid breakpoint";                    //$NON-NLS-1$
+    static final String UNKNOWN_BREAKPOINT           = "Unknown breakpoint";                    //$NON-NLS-1$
+    static final String INVALID_PARAMETER            = "Invalid breakpoint parameter(s)";       //$NON-NLS-1$
+
+    static final String NO_DEBUGGER_PATH             = "No debugger path for breakpoint";       //$NON-NLS-1$
+    static final String NO_MARKER_FOR_BREAKPOINT     = "No marker associated with breakpoint";  //$NON-NLS-1$
+
+    ///////////////////////////////////////////////////////////////////////////
+    // AbstractDsfService
+    ///////////////////////////////////////////////////////////////////////////
+
     /**
      * The service constructor.
      * Performs basic instantiation (method initialize() performs the real
@@ -35,6 +200,1515 @@
      * @param debugModelId  the debugging model
      */
     public MIBreakpointsManager(DsfSession session, String debugModelId) {
-        super(session, new MIBreakpointAttributeTranslator(session, debugModelId));
+        super(session);
+        fDebugModelId = debugModelId;
+    }
+
+    //-------------------------------------------------------------------------
+    // initialize
+    //-------------------------------------------------------------------------
+    // - Collect references for the services we interact with
+    // - Register to interesting events
+    // - Obtain the list of platform breakpoints
+    // - Register the service for interested parties
+    //-------------------------------------------------------------------------
+
+    /* (non-Javadoc)
+     * @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
+     */
+    @Override
+    public void initialize(final RequestMonitor rm) {
+        super.initialize(
+            new RequestMonitor(getExecutor(), rm) {
+                @Override
+                protected void handleSuccess() {
+                    doInitialize(rm);
+                }});
+    }
+
+    /**
+     * @param rm
+     */
+    private void doInitialize(RequestMonitor rm) {
+        
+        // Get the required services references from central repository
+        fConnection     = getServicesTracker().getService(ICommandControl.class);
+        fRunControl     = getServicesTracker().getService(IRunControl.class);
+        fSourceLookup   = getServicesTracker().getService(ISourceLookup.class);
+        fBreakpoints    = getServicesTracker().getService(IBreakpoints.class);
+        fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager();
+        fBreakpointActionManager = CDebugCorePlugin.getDefault().getBreakpointActionManager();
+
+        // Register to the useful events
+        getSession().addServiceEventListener(this, null);
+        fBreakpointManager.addBreakpointListener(this);
+        fBreakpointManager.addBreakpointManagerListener(this);
+
+        // And register this service
+        register(new String[] { MIBreakpointsManager.class.getName() },
+                 new Hashtable<String, String>());
+        rm.done();
+    }
+
+    //-------------------------------------------------------------------------
+    // shutdown
+    //-------------------------------------------------------------------------
+    // - Un-register the service
+    // - Stop listening to events
+    // - Remove the breakpoints installed by this service
+    //
+    //  Since we are shutting down, there is no overwhelming need
+    //  to keep the maps coherent...
+    //-------------------------------------------------------------------------
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.cdt.dsf.service.AbstractDsfService#shutdown(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
+     */
+    @Override
+    public void shutdown(final RequestMonitor rm) {
+
+        // Stop accepting requests and events
+        unregister();
+        getSession().removeServiceEventListener(this);
+        fBreakpointManager.removeBreakpointListener(this);
+        fBreakpointManager.removeBreakpointManagerListener(this);
+
+        // Cleanup the breakpoints that are still installed by the service.
+        // Use a counting monitor which will call mom to complete the shutdown
+        // after the breakpoints are un-installed (successfully or not).
+        CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
+            @Override
+            protected void handleCompleted() {
+                MIBreakpointsManager.super.shutdown(rm);
+            }
+        };
+
+        List<IBreakpointsTargetDMContext> targetBPKeys = new ArrayList<IBreakpointsTargetDMContext>(fTargetBPs.size());
+        targetBPKeys.addAll(0, fTargetBPs.keySet());
+        for (IBreakpointsTargetDMContext dmc : targetBPKeys) {
+            stopTrackingBreakpoints(dmc, countingRm);
+        }
+        countingRm.setDoneCount(targetBPKeys.size());
+    }
+
+    //-------------------------------------------------------------------------
+    // getBundleContext
+    //-------------------------------------------------------------------------
+
+    /* (non-Javadoc)
+     * @see org.eclipse.cdt.dsf.service.AbstractDsfService#getBundleContext()
+     */
+    @Override
+    protected BundleContext getBundleContext() {
+        return GdbPlugin.getBundleContext();
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // IBreakpointsManager
+    ///////////////////////////////////////////////////////////////////////////
+
+    //-------------------------------------------------------------------------
+    // startTrackingBreakpoints
+    //-------------------------------------------------------------------------
+    // - Augment the maps with the new execution context
+    // - Install the platform breakpoints on the selected target
+    //-------------------------------------------------------------------------
+
+    /**
+     * Install and begin tracking breakpoints for given context.  The service
+     * will keep installing new breakpoints that appear in the IDE for this
+     * context until {@link #uninstallBreakpoints(IDMContext)} is called for that
+     * context.
+     * @param dmc Context to start tracking breakpoints for.
+     * @param rm Completion callback.
+     */
+    public void startTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) {
+
+        // Validate the execution context
+        if (dmc == null) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_CONTEXT, null));
+            rm.done();
+            return;
+        }
+
+        // Make sure a mapping for this execution context does not already exist
+        Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformBPs.get(dmc);
+        Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
+        Map<IBreakpointDMContext, ICBreakpoint> targetIDs = fTargetBPs.get(dmc);
+        Map<ICBreakpoint, Set<String>> threadIDs = fBreakpointThreads.get(dmc);
+        if ((platformBPs != null) || (breakpointIDs != null) || (targetIDs != null) || (threadIDs != null)) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, CONTEXT_ALREADY_INITIALIZED, null));
+            rm.done();
+            return;
+        }
+
+        // Create entries in the breakpoint tables for the new context. These entries should only
+        // be removed when this service stops tracking breakpoints for the given context.
+        fPlatformBPs.put(dmc, new HashMap<ICBreakpoint, Map<String, Object>>());
+        fBreakpointIDs.put(dmc, new HashMap<ICBreakpoint, Vector<IBreakpointDMContext>>());
+        fTargetBPs.put(dmc, new HashMap<IBreakpointDMContext, ICBreakpoint>());
+        fBreakpointThreads.put(dmc, new HashMap<ICBreakpoint, Set<String>>());
+
+        // Install the platform breakpoints (stored in fPlatformBPs) on the target.
+        new Job("DSF BreakpointsManager: Install initial breakpoints on target") { //$NON-NLS-1$
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                // Submit the runnable to plant the breakpoints on dispatch thread.
+                getExecutor().submit(new Runnable() {
+                    public void run() {
+                        installInitialBreakpoints(dmc, rm);
+                    }
+                });
+
+                return Status.OK_STATUS;
+            }
+        }.schedule();
+    }
+
+    /**
+     * Installs the breakpoints that existed prior to the activation of this
+     * execution context.
+     * 
+     * @param dmc
+     * @param initialPlatformBPs
+     * @param rm
+     */
+    private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm)
+    {
+        // Retrieve the set of platform breakpoints for this context
+        final Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformBPs.get(dmc);
+        if (platformBPs == null) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null));
+            rm.done();
+            return;
+        }
+
+        // Read current breakpoints from platform and copy their augmented
+        // attributes into the local reference map
+        try {
+            IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(fDebugModelId);
+            for (IBreakpoint breakpoint : breakpoints) {
+                if (supportsBreakpoint(breakpoint)) {
+                    @SuppressWarnings("unchecked")
+                    Map<String, Object> attributes = breakpoint.getMarker().getAttributes();
+                    attributes.put(ATTR_DEBUGGER_PATH, NULL_STRING);
+                    attributes.put(ATTR_THREAD_FILTER, extractThreads(dmc, (ICBreakpoint) breakpoint));
+                    attributes.put(ATTR_THREAD_ID, NULL_STRING);
+                    platformBPs.put((ICBreakpoint) breakpoint, attributes);
+                }
+            }
+        } catch (CoreException e) {
+            IStatus status = new Status(
+                IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, UNABLE_TO_READ_BREAKPOINT, e);
+            rm.setStatus(status);
+            rm.done();
+        }
+
+        // Install the individual breakpoints on the dispatcher thread
+        // Requires a counting monitor to know when we are done
+        final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm);
+        countingRm.setDoneCount(platformBPs.size());
+
+        for (final ICBreakpoint breakpoint : platformBPs.keySet()) {
+            final Map<String, Object> attributes = platformBPs.get(breakpoint);
+            // Upon determining the debuggerPath, the breakpoint is installed
+            determineDebuggerPath(dmc, attributes, new RequestMonitor(getExecutor(), countingRm) {
+                @Override
+                protected void handleSuccess() {
+                	// Install only if the breakpoint is enabled at startup (Bug261082)
+                	boolean bpEnabled = attributes.get(ICBreakpoint.ENABLED).equals(true) && fBreakpointManager.isEnabled();
+                	if (bpEnabled)
+                		installBreakpoint(dmc, breakpoint, attributes, countingRm);
+                	else
+                		countingRm.done();
+                }
+            });
+        }
+    }
+
+    //-------------------------------------------------------------------------
+    // stopTrackingBreakpoints
+    //-------------------------------------------------------------------------
+    // - Remove the target breakpoints for the given execution context
+    // - Update the maps
+    //-------------------------------------------------------------------------
+
+    /**
+     * Uninstall and stop tracking breakpoints for the given context.
+     * @param dmc Context to start tracking breakpoints for.
+     * @param rm Completion callback.
+     */
+    public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) {
+
+        // Validate the context
+        if (dmc == null) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null));
+            rm.done();
+            return;
+        }
+
+        // Retrieve the set of platform breakpoints for this context
+        final Map<ICBreakpoint,Map<String, Object>> platformBPs = fPlatformBPs.get(dmc);
+        if (platformBPs == null) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, INVALID_CONTEXT, null));
+            rm.done();
+            return;
+        }
+
+        // Un-install the individual breakpoints on the dispatcher thread
+        // (requires a counting monitor to know when we are done).
+        // On completion (success or failure), update the maps.
+        final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
+            @Override
+            protected void handleCompleted() {
+                fPlatformBPs.remove(dmc);
+                fBreakpointIDs.remove(dmc);
+                fTargetBPs.remove(dmc);
+                fBreakpointThreads.remove(dmc);
+                rm.done();
+            }
+        };
+        countingRm.setDoneCount(platformBPs.size());
+
+        for (final ICBreakpoint breakpoint : platformBPs.keySet()) {
+            uninstallBreakpoint(dmc, breakpoint,
+                new RequestMonitor(getExecutor(), countingRm) {
+                    @Override
+                    protected void handleCompleted() {
+                        countingRm.done();
+                    }
+                });
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Back-end interface functions
+    ///////////////////////////////////////////////////////////////////////////
+
+    //-------------------------------------------------------------------------
+    // installBreakpoint
+    //-------------------------------------------------------------------------
+
+    /**
+     * Install a platform breakpoint on the back-end. For a given context, a
+     * platform breakpoint can resolve into multiple back-end breakpoints when
+     * threads are taken into account.
+     * 
+     * @param dmc
+     * @param breakpoint
+     * @param attributes
+     * @param rm
+     */
+    private void installBreakpoint(IBreakpointsTargetDMContext dmc, final ICBreakpoint breakpoint,
+        final Map<String, Object> attributes, final RequestMonitor rm)
+    {
+        // Retrieve the breakpoint maps
+        final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformBPs.get(dmc);
+        assert platformBPs != null;
+
+        final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
+        assert breakpointIDs != null;
+
+        final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fTargetBPs.get(dmc);
+        assert targetBPs != null;
+
+        final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
+        assert threadsIDs != null;
+
+        // Minimal validation
+        if (breakpointIDs.containsKey(breakpoint) || targetBPs.containsValue(breakpoint)) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_INSTALLED, null));
+            rm.done();
+            return;
+        }
+
+        // Ensure the breakpoint has a valid debugger source path
+        if (breakpoint instanceof ICLineBreakpoint && !(breakpoint instanceof ICAddressBreakpoint)) {
+            String debuggerPath = (String) attributes.get(ATTR_DEBUGGER_PATH);
+            if (debuggerPath == null || debuggerPath == NULL_STRING) {
+                rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, NO_DEBUGGER_PATH, null));
+                rm.done();
+                return;
+            }
+        }
+
+        // A back-end breakpoint needs to be installed for each specified thread
+        // Note: This is a bit academic since [1] thread info is not kept by the
+        // BreakpointManager (so it can not possibly be restored when a target is
+        // started), and [2] the standard GUI doesn't allow to specify thread at
+        // breakpoint creation. However, it is conceivable that an enhanced Editor
+        // would permit it.
+        final Set<String> threads = getThreads(attributes);
+
+        // Update the breakpoint state when all back-end breakpoints have been installed
+        final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) {
+            @Override
+            protected void handleCompleted() {
+                // Store the platform breakpoint
+                platformBPs.put(breakpoint, attributes);
+                rm.done();
+            }
+        };
+        installRM.setDoneCount(threads.size());
+
+        // Install the back-end breakpoint(s)
+        for (final String thread : threads) {
+            DataRequestMonitor<IBreakpointDMContext> drm =
+                new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), installRM) {
+                    @Override
+                    protected void handleSuccess() {
+                        // Add the new back-end breakpoint to the map
+                        Vector<IBreakpointDMContext> list = breakpointIDs.get(breakpoint);
+                        if (list == null)
+                            list = new Vector<IBreakpointDMContext>();
+                        IBreakpointDMContext targetBP = getData();
+                        list.add(targetBP);
+                        breakpointIDs.put(breakpoint, list);
+
+                        // Add the reverse mapping
+                        targetBPs.put(targetBP, breakpoint);
+
+                        // And update the corresponding thread list
+                        Set<String> thrds = threadsIDs.get(breakpoint);
+                        if (thrds == null)
+                            thrds = new HashSet<String>();
+                        thrds.add(thread);
+                        threadsIDs.put(breakpoint, thrds);
+
+                        // Reset the thread (is it necessary?)
+                        attributes.put(ATTR_THREAD_ID, NULL_STRING);
+
+                        // Remove breakpoint problem marker (if any)
+                        removeBreakpointProblemMarker(breakpoint);
+
+                        // Finally, update the platform breakpoint
+                        try {
+							breakpoint.incrementInstallCount();
+						} catch (CoreException e) {
+						}
+                        installRM.done();
+                    }
+
+                    @Override
+                    protected void handleError() {
+                        addBreakpointProblemMarker(breakpoint, "Breakpoint attribute problem: installation failed", IMarker.SEVERITY_WARNING); //$NON-NLS-1$
+                        installRM.done();
+                    }
+                };
+
+            // Convert the breakpoint attributes for the back-end
+            attributes.put(ATTR_THREAD_ID, thread);
+            Map<String,Object> targetAttributes = convertToTargetBreakpoint(breakpoint, attributes);
+            fBreakpoints.insertBreakpoint(dmc, targetAttributes, drm);
+        }
+    }
+
+    private void addBreakpointProblemMarker(final ICBreakpoint breakpoint, final String description, final int severity) {
+
+        new Job("Add Breakpoint Problem Marker") { //$NON-NLS-1$
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                
+                if (breakpoint instanceof ICLineBreakpoint) {
+                	// If we have already have a problem marker on this breakpoint
+                	// we should remove it first.
+                    IMarker marker = fBreakpointMarkerProblems.remove(breakpoint);
+                    if (marker != null) {
+                        try {
+                            marker.delete();
+                        } catch (CoreException e) {
+                        }
+                	}
+
+                    ICLineBreakpoint lineBreakpoint = (ICLineBreakpoint) breakpoint;
+                    try {
+                        // Locate the workspace resource via the breakpoint marker
+                        IMarker breakpoint_marker = lineBreakpoint.getMarker();
+                        IResource resource = breakpoint_marker.getResource();
+
+                        // Add a problem marker to the resource
+                        IMarker problem_marker = resource.createMarker(BreakpointProblems.BREAKPOINT_PROBLEM_MARKER_ID);
+                        int line_number = lineBreakpoint.getLineNumber();
+                        problem_marker.setAttribute(IMarker.LOCATION,    String.valueOf(line_number));
+                        problem_marker.setAttribute(IMarker.MESSAGE,     description);
+                        problem_marker.setAttribute(IMarker.SEVERITY,    severity);
+                        problem_marker.setAttribute(IMarker.LINE_NUMBER, line_number);
+
+                        // And save the baby
+                        fBreakpointMarkerProblems.put(breakpoint, problem_marker);
+                    } catch (CoreException e) {
+                    }
+                }
+                return Status.OK_STATUS;
+            }
+        }.schedule();
+    }
+
+    private void removeBreakpointProblemMarker(final ICBreakpoint breakpoint) {
+
+        new Job("Remove Breakpoint Problem Marker") { //$NON-NLS-1$
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                
+                IMarker marker = fBreakpointMarkerProblems.remove(breakpoint);
+                if (marker != null) {
+                    try {
+                        marker.delete();
+                    } catch (CoreException e) {
+                    }
+                }
+
+                return Status.OK_STATUS;
+            }
+        }.schedule();
+    }
+
+    //-------------------------------------------------------------------------
+    // uninstallBreakpoint
+    //-------------------------------------------------------------------------
+
+    /**
+     * Un-install an individual breakpoint on the back-end. For one platform
+     * breakpoint in a given execution context, there could be multiple
+     * corresponding back-end breakpoints (one per thread).
+     * 
+     * @param dmc
+     * @param breakpoint
+     * @param rm
+     */
+    private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc,
+            final ICBreakpoint breakpoint, final RequestMonitor rm)
+    {
+        // Retrieve the breakpoint maps
+        final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformBPs.get(dmc);
+        assert platformBPs != null;
+
+        final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
+        assert breakpointIDs != null;
+
+        final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fTargetBPs.get(dmc);
+        assert targetBPs != null;
+
+        final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
+        assert threadsIDs != null;
+
+        // Remove breakpoint problem marker (if any)
+        removeBreakpointProblemMarker(breakpoint);
+
+        // Minimal validation
+        if (!platformBPs.containsKey(breakpoint) || !breakpointIDs.containsKey(breakpoint) || !targetBPs.containsValue(breakpoint)) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_REMOVED, null));
+            rm.done();
+            return;
+        }
+
+        // Remove completion monitor
+        // Upon completion, update the mappings
+        CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) {
+            @Override
+            protected void handleSuccess() {
+                // Update the mappings
+                platformBPs.remove(breakpoint);
+                threadsIDs.remove(breakpoint);
+
+                Vector<IBreakpointDMContext> contexts = breakpointIDs.get(breakpoint);
+                if (contexts != null) {
+                    for (IBreakpointDMContext context : contexts)
+                        targetBPs.remove(context);
+                }
+
+                breakpointIDs.get(breakpoint).clear();
+                breakpointIDs.remove(breakpoint);
+
+                fPendingRequests.remove(breakpoint);
+
+				rm.done();
+            }
+        };
+
+        // Remove the back-end breakpoints
+        Vector<IBreakpointDMContext> list = breakpointIDs.get(breakpoint);
+        int count = 0;
+        if (list != null) {
+            for (IBreakpointDMContext bp : list) {
+                fBreakpoints.removeBreakpoint(bp, removeRM);
+                try {
+					breakpoint.decrementInstallCount();
+				} catch (CoreException e) {
+				}
+            }
+            count = list.size();
+        }
+        removeRM.setDoneCount(count);
+    }
+
+    //-------------------------------------------------------------------------
+    // modifyBreakpoint
+    //-------------------------------------------------------------------------
+
+    /**
+     * Modify a platform breakpoint which can translate to quite a few updates
+     * on the target...
+     * 
+     * @param dmc
+     * @param breakpoint
+     * @param attributes
+     * @param oldValues
+     * @param rm
+     */
+    private void modifyBreakpoint(final IBreakpointsTargetDMContext dmc, final ICBreakpoint breakpoint,
+            final Map<String,Object> attributes, final IMarkerDelta oldValues, final RequestMonitor rm)
+    {
+        // Retrieve the breakpoint maps
+        final Map<ICBreakpoint,Map<String,Object>> platformBPs = fPlatformBPs.get(dmc);
+        assert platformBPs != null;
+
+        final Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
+        assert breakpointIDs != null;
+
+        final Map<IBreakpointDMContext, ICBreakpoint> targetBPs = fTargetBPs.get(dmc);
+        assert targetBPs != null;
+
+        final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
+        assert threadsIDs != null;
+
+        // Minimal validation
+        if (!platformBPs.containsKey(breakpoint)) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, UNKNOWN_BREAKPOINT, null));
+            rm.done();
+            return;
+        }
+
+        // Check if the breakpoint is installed: it might not have been if it wasn't enabled at startup (Bug261082)
+        // Or the installation might have failed; in this case, we still try to install it again because
+        // some attribute might have changed which will make the install succeed.
+        if (!breakpointIDs.containsKey(breakpoint) && !targetBPs.containsValue(breakpoint)) {
+        	// Install only if the breakpoint is enabled
+        	boolean bpEnabled = attributes.get(ICBreakpoint.ENABLED).equals(true) && fBreakpointManager.isEnabled();
+        	if (bpEnabled) {
+                attributes.put(ATTR_DEBUGGER_PATH, NULL_STRING);
+                attributes.put(ATTR_THREAD_FILTER, extractThreads(dmc, breakpoint));
+                attributes.put(ATTR_THREAD_ID, NULL_STRING);
+                determineDebuggerPath(dmc, attributes, new RequestMonitor(getExecutor(), rm) {
+                    @Override
+                    protected void handleSuccess() {
+                      	installBreakpoint(dmc, breakpoint, attributes, rm);
+                    }
+                });
+        	}
+        	else {
+                rm.done();
+        	}
+       		return;
+        }
+
+        // Get the original breakpoint attributes
+        final Map<String,Object> original_attributes = platformBPs.get(breakpoint);
+        if (original_attributes == null) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, INVALID_BREAKPOINT, null));
+            rm.done();
+            return;
+        }
+
+        // Determine the attributes delta
+        final Map<String,Object> oldAttributes = new HashMap<String,Object>(original_attributes);
+        oldAttributes.put(ATTR_THREAD_FILTER, threadsIDs.get(breakpoint));
+
+        final Set<String> newThreads = extractThreads(dmc, breakpoint);
+        Map<String,Object> newAttributes = new HashMap<String,Object>(attributes);
+        newAttributes.put(ATTR_THREAD_FILTER, newThreads);
+
+        final Map<String,Object> attributesDelta = determineAttributesDelta(oldAttributes, newAttributes);
+
+        // Get the list of back-end breakpoints
+        final Vector<IBreakpointDMContext> oldTargetBPs = new Vector<IBreakpointDMContext>(breakpointIDs.get(breakpoint));
+        if (oldTargetBPs == null) {
+            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, INVALID_BREAKPOINT, null));
+            rm.done();
+            return;
+        }
+
+        // We're all set for the breakpoint update.
+        //
+        // The path for a simple update is straightforward:
+        // - For each back-end BP corresponding to a platform BP
+        //   - Send an update command to the back-end
+        //   - If the operation succeeded, update the data structures
+        //   - If the operation failed, try to roll-back
+        //
+        // In cases where the the back-end breakpoint cannot be
+        // simply updated (e.g. thread filter modification), the old
+        // breakpoint has to be removed and new one(s) inserted.
+        //
+        // The path for such an update is:
+        // - Install the updated breakpoint
+        // - In the operation succeeded
+        //   - Remove the old breakpoint(s)
+        //   - Perform any pending update
+
+        // Update completion monitor
+        final CountingRequestMonitor updateRM = new CountingRequestMonitor(getExecutor(), rm) {
+            @Override
+            protected void handleSuccess() {
+                // Success: simply store the new attributes
+                platformBPs.put(breakpoint, attributes);
+                rm.done();
+            }
+
+            @Override
+            protected void handleError() {
+                // Reset the breakpoint attributes. This will trigger a
+                // breakpoint change event and the correct delta will be
+                // computed, resulting in a correctly restored breakpoint
+                // at the back-end.
+                rollbackAttributes(breakpoint, oldValues);
+                platformBPs.put(breakpoint, attributes);
+
+                rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null));
+                rm.done();
+            }
+        };
+
+        // Everything OK: remove the old back-end breakpoints
+        final Vector<IBreakpointDMContext> newTargetBPs = new Vector<IBreakpointDMContext>();
+        final CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) {
+            @Override
+            protected void handleSuccess() {
+                // All right! Save the new list and perform the final update
+                Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpointIDs = fBreakpointIDs.get(dmc);
+                if (breakpointIDs == null) {
+                    rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_BREAKPOINT, null));
+                    rm.done();
+                    return;
+                }
+                breakpointIDs.put(breakpoint, newTargetBPs);
+                for (IBreakpointDMContext ref : newTargetBPs) {
+                    fBreakpoints.updateBreakpoint(ref, attributesDelta, updateRM);
+                }
+                updateRM.setDoneCount(newTargetBPs.size());
+            }};
+
+        // New back-end breakpoints insertion monitor
+        // Holds the list of new back-end breakpoint contexts of the platform breakpoint
+        final DataRequestMonitor<Vector<IBreakpointDMContext>> insertRM =
+            new DataRequestMonitor<Vector<IBreakpointDMContext>>(getExecutor(), null) {
+
+                @Override
+                // In theory, we could have had a partial success and the original threads
+                // list would be invalid. We think it is highly unlikely so we assume that
+                // either everything went fine or else everything failed.
+                protected void handleSuccess() {
+                    // Get the list of new back-end breakpoints contexts
+                    newTargetBPs.addAll(getData());
+                    threadsIDs.put(breakpoint, newThreads);
+                    for (IBreakpointDMContext ref : oldTargetBPs) {
+                        fBreakpoints.removeBreakpoint(ref, removeRM);
+                        try {
+							breakpoint.decrementInstallCount();  // A tad early but it should work...
+						} catch (CoreException e) {
+						}
+                    }
+                    removeRM.setDoneCount(oldTargetBPs.size());
+                }
+                
+                @Override
+                protected void handleError() {
+                    // Keep the old threads list and reset the attributes
+                    // (bad attributes are the likely cause of failure)
+                    updateRM.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null));
+                    updateRM.setDoneCount(0);
+                }
+        };
+
+        // If the changes in the breakpoint attributes justify it, install a
+        // new set of back-end breakpoint(s) and then update them
+        if (needsResinstallation(attributesDelta)) {
+            reinstallBreakpoint(dmc, breakpoint, attributes, newThreads, insertRM);
+        }
+        else {
+            // Update the back-end breakpoint(s) state
+            for (IBreakpointDMContext ref : oldTargetBPs) {
+                fBreakpoints.updateBreakpoint(ref, attributesDelta, updateRM);
+            }
+            updateRM.setDoneCount(oldTargetBPs.size());
+        }
     }
+
+    /**
+     * Re-install the back-end breakpoints
+     * 
+     * @param context       the target context
+     * @param breakpoint    the platform breakpoint
+     * @param attributes    breakpoint augmented attributes
+     * @param threads       list of threads where breakpoint is to be installed
+     * @param drm           will contain the list of successfully installed back-end breakpoints
+     */
+    private void reinstallBreakpoint(final IBreakpointsTargetDMContext context, final ICBreakpoint breakpoint,
+            final Map<String,Object> attributes, Set<String> threads, final DataRequestMonitor<Vector<IBreakpointDMContext>> drm)
+    {
+        // Our new list of back-end breakpoints. Built as we go.
+        final Vector<IBreakpointDMContext> breakpointList = new Vector<IBreakpointDMContext>();
+
+        // Counting monitor for the new back-end breakpoints to install
+        // Once we're done, return the new list of back-end breakpoints contexts
+        final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), drm) {
+            @Override
+            protected void handleSuccess() {
+                // Report whatever we have managed to install
+                // It is very likely installation either succeeded or failed for all
+                drm.setData(breakpointList);
+                drm.done();
+            }
+        };
+        installRM.setDoneCount(threads.size());
+
+        // And install the new back-end breakpoints
+        for (String thread : threads) {
+            // Convert the breakpoint attributes for the back-end
+            // Refresh the set of attributes at each iteration just in case...
+            Map<String,Object> attrs = convertToTargetBreakpoint(breakpoint, attributes);
+            if (!fBreakpointManager.isEnabled()) {
+                attrs.put(MIBreakpoints.IS_ENABLED, false);
+            }
+            // Add the secret ingredient..
+            attrs.put(MIBreakpointDMData.THREAD_ID, thread);
+
+            // Then install the spiked breakpoint
+            fBreakpoints.insertBreakpoint(context, attrs,
+                new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), installRM) {
+                    @Override
+                    protected void handleSuccess() {
+                        // Add the new back-end breakpoint context to the list
+                        breakpointList.add(getData());
+                        try {
+							breakpoint.incrementInstallCount();
+						} catch (CoreException e) {
+						}
+                        installRM.done();
+                    }
+
+                    @Override
+                    protected void handleError() {
+                        // Add the new back-end breakpoint context to the list
+                        installRM.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, INVALID_PARAMETER, null));
+                        installRM.done();
+                    }
+            });
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // IBreakpointManagerListener implementation
+    ///////////////////////////////////////////////////////////////////////////
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.IBreakpointManagerListener#breakpointManagerEnablementChanged(boolean)
+     */
+    public void breakpointManagerEnablementChanged(boolean enabled) {
+
+        // Only modify enabled breakpoints
+        for (IBreakpointsTargetDMContext context : fBreakpointIDs.keySet()) {
+            for (ICBreakpoint breakpoint : fBreakpointIDs.get(context).keySet()) {
+                try {
+                    if (breakpoint.isEnabled()) {
+                        for (IBreakpointDMContext ref : fBreakpointIDs.get(context).get(breakpoint)) {
+                            Map<String,Object> delta = new HashMap<String,Object>();
+                            delta.put(MIBreakpoints.IS_ENABLED, enabled);
+                            fBreakpoints.updateBreakpoint(ref, delta, new RequestMonitor(getExecutor(), null));
+                        }
+                    }
+                } catch (CoreException e) {
+                }
+            }
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // IBreakpointListener implementation
+    ///////////////////////////////////////////////////////////////////////////
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
+     */
+    @ThreadSafe
+    public void breakpointAdded(final IBreakpoint breakpoint) {
+
+        if (supportsBreakpoint(breakpoint)) {
+            try {
+                // Retrieve the breakpoint attributes
+                @SuppressWarnings("unchecked")
+                final Map<String, Object> attrs = breakpoint.getMarker().getAttributes();
+
+                getExecutor().execute(new DsfRunnable() {
+                    public void run() {
+                        final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) {
+                            @Override
+                            protected void handleError() {
+                                if (getStatus().getSeverity() == IStatus.ERROR) {
+                                    GdbPlugin.getDefault().getLog().log(getStatus());
+                                }
+                            }
+                        };
+                        countingRm.setDoneCount(fPlatformBPs.size());
+
+                        // Install the breakpoint in all the execution contexts
+                        for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
+                            determineDebuggerPath(dmc, attrs,
+                                    new RequestMonitor(getExecutor(), countingRm) {
+                                    @Override
+                                    protected void handleSuccess() {
+                                        installBreakpoint(dmc, (ICBreakpoint) breakpoint,
+                                            attrs, countingRm);
+                                    }
+                                });
+                        }
+                    }
+                });
+            } catch (CoreException e) {
+            } catch (RejectedExecutionException e) {
+            }
+        }
+    }
+
+    /**
+     * @param bp
+     * @return
+     * @throws CoreException
+     */
+    private IDsfBreakpointExtension getFilterExtension(ICBreakpoint bp) throws CoreException {
+        return (IDsfBreakpointExtension) bp.getExtension(GDB_DEBUG_MODEL_ID, ICBreakpointExtension.class);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
+     */
+    public void breakpointChanged(final IBreakpoint breakpoint, final IMarkerDelta delta) {
+
+        if (supportsBreakpoint(breakpoint)) {
+
+            try {
+                // Retrieve the breakpoint attributes
+                @SuppressWarnings("unchecked")
+                final Map<String, Object> attrs = breakpoint.getMarker().getAttributes();
+                if (!fBreakpointManager.isEnabled()) {
+                    attrs.put(ICBreakpoint.ENABLED, false);
+                }
+
+                // Modify the breakpoint in all the target contexts
+                getExecutor().execute( new DsfRunnable() {
+                    public void run() {
+
+                        // If the breakpoint is currently being updated, queue the request and exit
+                        if (fPendingRequests.contains(breakpoint)) {
+                            fPendingBreakpoints.add(breakpoint);
+                            return;
+                        }
+
+                        // Keep track of the updates
+                        final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) {
+                            @Override
+                            protected void handleCompleted() {
+
+                                if (!isSuccess()) {
+                                    if (getStatus().getSeverity() == IStatus.ERROR) {
+                                        GdbPlugin.getDefault().getLog().log(getStatus());
+                                    }
+                                }
+
+                                // Indicate that the pending request has completed
+                                fPendingRequests.remove(breakpoint);
+
+                                // Process the next pending update for this breakpoint
+                                if (fPendingBreakpoints.contains(breakpoint)) {
+                                    fPendingBreakpoints.remove(breakpoint);
+                                    breakpointChanged(breakpoint, delta);
+                                }
+                            }
+                        };
+                        countingRm.setDoneCount(fPlatformBPs.size());
+
+                        // Mark the breakpoint as being updated and go
+                        fPendingRequests.add(breakpoint);
+                        
+                        // Modify the breakpoint in all the execution contexts
+                        for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
+                            determineDebuggerPath(dmc, attrs,
+                                new RequestMonitor(getExecutor(), countingRm) {
+                                    @Override
+                                    protected void handleSuccess() {
+                                        modifyBreakpoint(dmc, (ICBreakpoint) breakpoint, attrs, delta, new RequestMonitor(getExecutor(), countingRm));
+                                    }
+                                 });
+                        }
+                    }
+                });
+            } catch (CoreException e) {
+            } catch (RejectedExecutionException e) {
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
+     */
+    public void breakpointRemoved(final IBreakpoint breakpoint, IMarkerDelta delta) {
+
+        if (supportsBreakpoint(breakpoint)) {
+            try {
+                getExecutor().execute(new DsfRunnable() {
+                    public void run() {
+                        CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) {
+                            @Override
+                            protected void handleError() {
+                                if (getStatus().getSeverity() == IStatus.ERROR) {
+                                    GdbPlugin.getDefault().getLog().log(getStatus());
+                                }
+                            }
+                        };
+                        countingRm.setDoneCount(fPlatformBPs.size());
+
+                        // Remove the breakpoint in all the execution contexts
+                        for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
+                            if (fPlatformBPs.get(dmc).containsKey(breakpoint)) {
+                                uninstallBreakpoint(dmc, (ICBreakpoint) breakpoint, countingRm);
+                            }
+                        }
+                    }
+                });
+            } catch (RejectedExecutionException e) {
+            }
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // IServiceEventListener
+    ///////////////////////////////////////////////////////////////////////////
+
+    //-------------------------------------------------------------------------
+    // Breakpoints
+    //-------------------------------------------------------------------------
+
+    @DsfServiceEventHandler
+    public void eventDispatched(BreakpointAddedEvent e) {
+    	// Nothing to do - already handled by breakpointAdded()
+    }
+
+    @DsfServiceEventHandler
+    public void eventDispatched(BreakpointUpdatedEvent e) {
+    	// Nothing to do - already handled by breakpointChanged()
+    }
+
+    @DsfServiceEventHandler
+    public void eventDispatched(BreakpointRemovedEvent e) {
+    	// Nothing to do - already handled by breakpointRemoved()
+    }
+
+    /*
+     * When a watchpoint goes out of scope, it is automatically removed from
+     * the back-end. To keep our internal state synchronized, we have to
+     * remove it from our breakpoints maps.
+     * Unfortunately, GDB doesn't generate the correct event...
+     */
+    @DsfServiceEventHandler
+    public void eventDispatched(MIWatchpointScopeEvent e) {
+    }
+
+    //-------------------------------------------------------------------------
+    // Breakpoint actions
+    //-------------------------------------------------------------------------
+
+	@DsfServiceEventHandler 
+    public void eventDispatched(SuspendedEvent e) {
+
+		if (e.getMIEvent() instanceof MIBreakpointHitEvent) {
+			MIBreakpointHitEvent evt = (MIBreakpointHitEvent) e.getMIEvent();
+	        performBreakpointAction(evt.getDMContext(), evt.getNumber());
+	        return;
+		}
+
+		if (e.getMIEvent() instanceof MIWatchpointTriggerEvent) {
+			MIWatchpointTriggerEvent evt = (MIWatchpointTriggerEvent) e.getMIEvent();
+	        performBreakpointAction(evt.getDMContext(), evt.getNumber());
+	        return;
+		}
+	}
+
+    private void performBreakpointAction(final IDMContext context, int number) {
+        // Identify the platform breakpoint
+        final ICBreakpoint breakpoint = findPlatformBreakpoint(number);
+
+        // Perform the actions asynchronously (otherwise we can have a deadlock...)
+        new Job("Breakpoint action") { //$NON-NLS-1$
+            { setSystem(true); }
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                fBreakpointActionManager.executeActions(breakpoint, new BreakpointActionAdapter(getExecutor(), getServicesTracker(), context));
+                return Status.OK_STATUS;
+            };
+        }.schedule();
+    }
+
+    // Helper function to locate the platform breakpoint corresponding
+    // to the target breakpoint/watchpoint that was just hit
+
+    // FIXME: (Bug228703) Need a way to identify the correct context where the BP was hit
+    private ICBreakpoint findPlatformBreakpoint(int targetBreakpointID) {
+        Set<IBreakpointsTargetDMContext> targets = fTargetBPs.keySet();
+        for (IBreakpointsTargetDMContext target : targets) {
+            Map<IBreakpointDMContext, ICBreakpoint> bps = fTargetBPs.get(target);
+            Set<IBreakpointDMContext> contexts = bps.keySet();
+            for (IBreakpointDMContext context : contexts) {
+                if (context instanceof MIBreakpointDMContext) {
+                    MIBreakpointDMContext ctx = (MIBreakpointDMContext) context;
+                    if (ctx.getReference() == targetBreakpointID) {
+                        return bps.get(context);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    //-------------------------------------------------------------------------
+    // Session exit
+    //-------------------------------------------------------------------------
+
+    /**
+     * @since 1.1
+     * @nooverride This method is not intended to be re-implemented or extended by clients.
+     * @noreference This method is not intended to be referenced by clients.
+     */
+    @DsfServiceEventHandler
+    public void eventDispatched(ICommandControlShutdownDMEvent e) {
+        terminated();
+    }
+
+    private void terminated() {
+    	// Reset the breakpoint install count
+    	for (IBreakpointsTargetDMContext ctx : fPlatformBPs.keySet()) {
+    		Map<ICBreakpoint, Map<String, Object>> breakpoints = fPlatformBPs.get(ctx);
+            clearBreakpointStatus(breakpoints.keySet().toArray(new ICBreakpoint[breakpoints.size()]), ctx);
+    	}
+    	// This will prevent Shutdown() from trying to remove bps from a
+    	// backend that has already shutdown
+        fPlatformBPs.clear();
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Breakpoint status handling functions
+    ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     * @param bps
+     */
+    private void clearBreakpointStatus(final ICBreakpoint[] bps, final IBreakpointsTargetDMContext ctx)
+    {
+        new Job("Clear Breakpoints Status") { //$NON-NLS-1$
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                IWorkspaceRunnable wr = new IWorkspaceRunnable() {
+                    public void run(IProgressMonitor monitor) throws CoreException {
+                    	// For every platform breakpoint that has at least one target breakpoint installed
+                    	// we must decrement the install count, for every target breakpoint.
+                    	// Note that we cannot simply call resetInstallCount() because another
+                    	// launch may be using the same platform breakpoint.
+                    	Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpoints = fBreakpointIDs.get(ctx);
+                    	for (ICBreakpoint breakpoint : breakpoints.keySet()) {
+                    		Vector<IBreakpointDMContext> targetBps = breakpoints.get(breakpoint);
+                    		for (int i=0; i<targetBps.size(); i++) {
+                    			breakpoint.decrementInstallCount();
+                    		}
+                        }
+                    }
+                };
+
+                // First clear any problem markers
+                for (IMarker marker : fBreakpointMarkerProblems.values()) {
+                	if (marker != null) {
+                		try {
+							marker.delete();
+						} catch (CoreException e) {
+						}
+                	}
+                }
+                fBreakpointMarkerProblems.clear();
+                
+                // Create the scheduling rule to clear all bp planted.
+                ISchedulingRule rule = null;
+                List<ISchedulingRule> markerRules = new ArrayList<ISchedulingRule>();
+                for (ICBreakpoint bp : bps) {
+                    IMarker marker = bp.getMarker();
+                    if (marker != null) {
+                        ISchedulingRule markerRule =
+                            ResourcesPlugin.getWorkspace().getRuleFactory().markerRule(
+                                    marker.getResource());
+                        if (markerRule == null) {
+                            markerRules = null;
+                            break;
+                        } else {
+                            markerRules.add(markerRule);
+                        }
+                    }
+                }
+                if (markerRules != null) {
+                    rule = MultiRule.combine(markerRules.toArray(new ISchedulingRule[markerRules.size()]));
+                }
+
+                try {
+                    ResourcesPlugin.getWorkspace().run(wr, rule, 0, null);
+                } catch (CoreException e) {
+                    return e.getStatus();
+                }
+                return Status.OK_STATUS;
+            }
+        }.schedule();
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Support functions
+    ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     * supportsBreakpoint
+     * 
+     * Indicates if it is breakpoint we can deal with. For now, it boils down
+     * to a CDI breakpoint...
+     * 
+     * @param bp
+     * @return
+     */
+    private boolean supportsBreakpoint(IBreakpoint bp) {
+        if (bp instanceof ICBreakpoint && bp.getModelIdentifier().equals(fDebugModelId)) {
+            IMarker marker = bp.getMarker();
+            if (marker != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * determineDebuggerPath
+     * 
+     * Adds the path to the source file to the set of attributes
+     * (for the debugger).
+     * 
+     * @param dmc
+     * @param attributes
+     * @param rm
+     */
+    private void determineDebuggerPath(IBreakpointsTargetDMContext dmc,
+            final Map<String, Object> attributes, final RequestMonitor rm)
+    {
+        String hostPath = (String) attributes.get(ICBreakpoint.SOURCE_HANDLE);
+
+        if (hostPath != null) {
+
+            ISourceLookupDMContext srcDmc = DMContexts.getAncestorOfType(dmc, ISourceLookupDMContext.class);
+            if (srcDmc != null) {
+                fSourceLookup.getDebuggerPath(srcDmc, hostPath,
+                    new DataRequestMonitor<String>(getExecutor(), rm) {
+                        @Override
+                        protected void handleSuccess() {
+                            attributes.put(ATTR_DEBUGGER_PATH, adjustDebuggerPath(getData()));
+                            rm.done();
+                        }
+                    });
+            } else {
+                // Source lookup not available for given context, use the host
+                // path for the debugger path.
+                attributes.put(ATTR_DEBUGGER_PATH, adjustDebuggerPath(hostPath));
+                rm.done();
+            }
+        } else {
+            // Some types of breakpoints do not require a path
+            // (e.g. watchpoints)
+            rm.done();
+        }
+    }
+
+    /**
+     * See bug232415
+     * 
+     * @param path	the absolute path to the source file
+     * @return
+     */
+    private String adjustDebuggerPath(String path) {
+    	String result = path;
+    	// Make it MinGW-specific
+    	if (Platform.getOS().startsWith("win")) { //$NON-NLS-1$
+        	if (!path.startsWith("/")) { //$NON-NLS-1$
+        		result = path.substring(path.lastIndexOf('\\') + 1);
+        	}
+    	}
+    	return result;
+    }
+
+    /**
+     * Determine the set of modified attributes.
+     * Elementary set operations in full action :-)
+     * 
+     * @param oldAttributes
+     * @param newAttributes
+     * @return
+     */
+    private Map<String, Object> determineAttributesDelta(Map<String, Object> oldAttributes, Map<String, Object> newAttributes) {
+
+        Map<String, Object> delta = new HashMap<String,Object>();
+
+        Set<String> oldKeySet = oldAttributes.keySet();
+        Set<String> newKeySet = newAttributes.keySet();
+
+        Set<String> commonKeys  = new HashSet<String>(newKeySet); commonKeys.retainAll(oldKeySet);
+        Set<String> addedKeys   = new HashSet<String>(newKeySet); addedKeys.removeAll(oldKeySet);
+        Set<String> removedKeys = new HashSet<String>(oldKeySet); removedKeys.removeAll(newKeySet);
+
+        // Add the modified attributes
+        for (String key : commonKeys) {
+            if (!(oldAttributes.get(key).equals(newAttributes.get(key))))
+                delta.put(key, newAttributes.get(key));
+        }
+
+        // Add the new attributes
+        for (String key : addedKeys) {
+            delta.put(key, newAttributes.get(key));
+        }
+
+        // Remove the deleted attributes
+        for (String key : removedKeys) {
+            delta.put(key, null);
+        }
+
+        return convertedAttributes(delta);
+    }
+
+    /**
+     * Converts ICBreakpoint attributes to IBreakpoints attributes.
+     * 
+     * @param cdt_attributes
+     * @return
+     */
+    private Map<String, Object> convertedAttributes(Map<String, Object> cdt_attributes) {
+
+        Map<String,Object> result = new HashMap<String,Object>();
+
+        // IBreakpoint attributes
+        if (cdt_attributes.containsKey(ATTR_DEBUGGER_PATH))
+            result.put(MIBreakpoints.FILE_NAME, cdt_attributes.get(ATTR_DEBUGGER_PATH));
+            
+        if (cdt_attributes.containsKey(IMarker.LINE_NUMBER))
+            result.put(MIBreakpoints.LINE_NUMBER, cdt_attributes.get(IMarker.LINE_NUMBER));
+            
+        // ICLineBreakpoint attributes
+        if (cdt_attributes.containsKey(ICLineBreakpoint.FUNCTION))
+            result.put(MIBreakpoints.FUNCTION, cdt_attributes.get(ICLineBreakpoint.FUNCTION));
+            
+        if (cdt_attributes.containsKey(ICLineBreakpoint.ADDRESS))
+            result.put(MIBreakpoints.ADDRESS, cdt_attributes.get(ICLineBreakpoint.ADDRESS));
+            
+        // ICBreakpoint attributes
+        if (cdt_attributes.containsKey(ICBreakpoint.CONDITION))
+            result.put(MIBreakpoints.CONDITION, cdt_attributes.get(ICBreakpoint.CONDITION));
+            
+        if (cdt_attributes.containsKey(ICBreakpoint.IGNORE_COUNT))
+            result.put(MIBreakpoints.IGNORE_COUNT, cdt_attributes.get(ICBreakpoint.IGNORE_COUNT));
+
+        if (cdt_attributes.containsKey(ICBreakpoint.ENABLED))
+            result.put(MIBreakpoints.IS_ENABLED, cdt_attributes.get(ICBreakpoint.ENABLED));
+
+        // ICWatchpoint attributes
+        if (cdt_attributes.containsKey(ICWatchpoint.EXPRESSION))
+            result.put(MIBreakpoints.EXPRESSION, cdt_attributes.get(ICWatchpoint.EXPRESSION));
+
+        if (cdt_attributes.containsKey(ICWatchpoint.READ))
+            result.put(MIBreakpoints.READ, cdt_attributes.get(ICWatchpoint.READ));
+        
+        if (cdt_attributes.containsKey(ICWatchpoint.WRITE))
+            result.put(MIBreakpoints.WRITE, cdt_attributes.get(ICWatchpoint.WRITE));
+
+        // Threads
+        if (cdt_attributes.containsKey(ATTR_THREAD_FILTER))
+            result.put(ATTR_THREAD_FILTER, cdt_attributes.get(ATTR_THREAD_FILTER));
+
+        return result;
+    }
+
+    /**
+     * Figure out the corresponding number of back-end breakpoints
+     * Even though the thread IDs are usually integers, they are
+     * stored as strings in CBreakpoints.
+     * 
+     * @param attributes
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    private Set<String> getThreads(Map<String, Object> attributes) {
+        Set<String> threads = (Set<String>) attributes.get(ATTR_THREAD_FILTER);
+        if (threads == null) {
+            threads = new HashSet<String>();
+            threads.add("0");    // Thread 0 means all threads //$NON-NLS-1$
+        }
+        return threads;
+    }
+
+    /**
+     * Get the list of threads from the platform breakpoint attributes
+     * 
+     * @param breakpoint
+     * @return
+     */
+    private Set<String> extractThreads(IBreakpointsTargetDMContext context, ICBreakpoint breakpoint) {
+        Set<String> results = new HashSet<String>();
+
+        // Find the ancestor
+        List<IExecutionDMContext[]> threads = new ArrayList<IExecutionDMContext[]>(1);
+
+        try {
+            // Retrieve the targets
+            IDsfBreakpointExtension filterExtension = getFilterExtension(breakpoint);
+            IContainerDMContext[] targets = filterExtension.getTargetFilters();
+
+            // If no target is present, breakpoint applies to all.
+            if (targets.length == 0) {
+                results.add("0"); //$NON-NLS-1$    
+                return results;
+            }
+
+            // Extract the thread IDs (if there is none, we are covered)
+            for (IContainerDMContext ctxt : targets) {
+                if (DMContexts.isAncestorOf(ctxt, context)) {
+                    threads.add(filterExtension.getThreadFilters(ctxt));
+                }
+            }
+        } catch (CoreException e1) {
+        }
+
+        if (supportsThreads(breakpoint)) {
+            for (IExecutionDMContext[] targetThreads : threads) {
+                if (targetThreads != null) {
+                    for (IExecutionDMContext thread : targetThreads) {
+                        if (thread instanceof IMIExecutionDMContext) {
+                        	IMIExecutionDMContext dmc = (IMIExecutionDMContext) thread;
+                            results.add(((Integer) dmc.getThreadId()).toString());
+                        }
+                    }
+                } else {
+                    results.add("0"); //$NON-NLS-1$    
+                    break;
+                }
+            }
+        } else {
+            results.add("0"); //$NON-NLS-1$
+        }
+
+        return results;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Non-generic (MI-specific) functions
+    ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Create a target breakpoint from an ICBreakpoint
+     * 
+     * @param breakpoint
+     * @param attributes
+     * @return
+     */
+    protected Map<String,Object> convertToTargetBreakpoint(ICBreakpoint breakpoint, Map<String,Object> attributes) {
+
+        Map<String, Object> properties = new HashMap<String, Object>();
+
+        if (breakpoint instanceof ICWatchpoint) {
+            // Convert the CDI watchpoint to an IBreakpoint
+            properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.WATCHPOINT);
+            properties.put(MIBreakpoints.EXPRESSION,      attributes.get(ICWatchpoint.EXPRESSION));
+            properties.put(MIBreakpoints.READ,            attributes.get(ICWatchpoint.READ));
+            properties.put(MIBreakpoints.WRITE,           attributes.get(ICWatchpoint.WRITE));
+        }
+        else if (breakpoint instanceof ICLineBreakpoint) {
+            // Convert the CDI breakpoint to an IBreakpoint
+            properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
+            properties.put(MIBreakpoints.FILE_NAME,       attributes.get(ATTR_DEBUGGER_PATH));
+            properties.put(MIBreakpoints.LINE_NUMBER,     attributes.get(IMarker.LINE_NUMBER));
+            properties.put(MIBreakpoints.FUNCTION,        attributes.get(ICLineBreakpoint.FUNCTION));
+            properties.put(MIBreakpoints.ADDRESS,         attributes.get(ICLineBreakpoint.ADDRESS));
+        } else {
+        	// catchpoint?
+        }
+
+        // Common fields
+        properties.put(MIBreakpoints.CONDITION,           attributes.get(ICBreakpoint.CONDITION));
+        properties.put(MIBreakpoints.IGNORE_COUNT,        attributes.get(ICBreakpoint.IGNORE_COUNT));
+        properties.put(MIBreakpoints.IS_ENABLED,          attributes.get(ICBreakpoint.ENABLED));
+        properties.put(MIBreakpointDMData.THREAD_ID,      attributes.get(ATTR_THREAD_ID));
+
+        // Adjust for "skip-all"
+        if (!fBreakpointManager.isEnabled()) {
+            properties.put(MIBreakpoints.IS_ENABLED, false);
+        }
+
+        return properties;
+    }
+
+    /**
+     * Determine if the modified attributes necessitate
+     * a breakpoint removal/re-installation
+     * 
+     * @param delta
+     * @return
+     */
+    protected boolean needsResinstallation(Map<String,Object> delta) {
+        
+        // Check if there is any modified attribute
+        if (delta == null)
+            return false;
+
+        // Check the "critical" attributes
+        if (delta.containsKey(ATTR_DEBUGGER_PATH)            // File name
+        ||  delta.containsKey(MIBreakpoints.LINE_NUMBER)     // Line number
+        ||  delta.containsKey(MIBreakpoints.FUNCTION)        // Function name
+        ||  delta.containsKey(MIBreakpoints.ADDRESS)         // Absolute address
+        ||  delta.containsKey(ATTR_THREAD_FILTER)            // Thread ID
+        ||  delta.containsKey(MIBreakpoints.EXPRESSION)      // Watchpoint expression
+        ||  delta.containsKey(MIBreakpoints.READ)            // Watchpoint type
+        ||  delta.containsKey(MIBreakpoints.WRITE)) {        // Watchpoint type
+            return true;
+        }
+
+         return false;
+    }
+
+    /**
+     * @param breakpoint
+     * @param oldValues
+     */
+    protected void rollbackAttributes(ICBreakpoint breakpoint, IMarkerDelta oldValues) {
+
+        try {
+            String new_condition = breakpoint.getCondition();
+            if (new_condition == null)
+                new_condition = NULL_STRING;
+            String old_condition = (oldValues != null) ? oldValues.getAttribute(ICBreakpoint.CONDITION, NULL_STRING) : NULL_STRING;
+            if (!old_condition.equals(new_condition)) {
+                breakpoint.setCondition(old_condition);
+            }
+            else {
+                breakpoint.setCondition(NULL_STRING);
+            }
+        } catch (CoreException e) {
+        }
+    }
+
+    /**
+     * Indicates if the back-end supports multiple threads for
+     * this type of breakpoint
+     * 
+     * @param breakpoint
+     */
+    protected boolean supportsThreads(ICBreakpoint breakpoint) {
+
+        return !(breakpoint instanceof ICWatchpoint);
+    }
+
 }
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java	Fri Dec 04 14:31:59 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java	Fri Dec 04 14:32:55 2009 -0600
@@ -7,14 +7,12 @@
  *
  * Contributors:
  *     Wind River - Initial API and implementation
- *     Ericsson   - Low-level breakpoints integration
- *     Nokia - refactored to work for both GDB and EDC.  Nov. 2009.
+ *     Ericsson   - Low-level breakpoints integration  
  *******************************************************************************/
 
 package org.eclipse.cdt.dsf.debug.service;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -27,9 +25,9 @@
 import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
 import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
 import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
-import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
 import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
 import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
+import org.eclipse.cdt.dsf.datamodel.DMContexts;
 import org.eclipse.cdt.dsf.datamodel.IDMContext;
 import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
 import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
@@ -43,177 +41,76 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointListener;
 import org.eclipse.debug.core.IBreakpointManager;
 import org.eclipse.debug.core.IBreakpointManagerListener;
-import org.eclipse.debug.core.IBreakpointsListener;
 import org.eclipse.debug.core.model.IBreakpoint;
 import org.osgi.framework.BundleContext;
 
 /**
- * see these bugs for design of this service.<br>
- * - https://bugs.eclipse.org/bugs/show_bug.cgi?id=218557
- * - https://bugs.eclipse.org/bugs/show_bug.cgi?id=292468
+ * 
  */
-public class BreakpointsMediator extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointsListener
+public class BreakpointsMediator extends AbstractDsfService implements IBreakpointManagerListener, IBreakpointListener
 {
-	public enum BreakpointEventType {ADDED, REMOVED, MODIFIED}; 	
-	
+
     /**
      * The attribute translator that this service will use to map the platform
-     * breakpoint attributes to the corresponding target attributes, and vice
+     * breakpiont attributes to the corresponding target attributes, and vice
      * versa.
      */
     private IBreakpointAttributeTranslator fAttributeTranslator;
-    
-    /**
-     * If the attribute translator implements the {@link IBreakpointAttributeTranslatorExtension},
-     * this field will be valid, otherwise it is null.
-     */
-    private IBreakpointAttributeTranslatorExtension fAttributeTranslator2;
 
     /**
      * DSF Debug service for creating breakpoints.
      */
-    IBreakpoints fBreakpointsService;
+    IBreakpoints fBreakpoints;
     
     /**
      * Platform breakpoint manager
      */
     IBreakpointManager fBreakpointManager;
-
-    /**
-     * Object describing the information about a single target breakpoint  
-     * corresponding to specific platform breakpoint and breakpoint target 
-     * context.
-     * 
-     * @since 2.1
-     */
-    public interface ITargetBreakpointInfo {
-
-    	/**
-    	 * Returns the breakpoint attributes as returned by the attribute translator.
-    	 */
-    	public Map<String, Object> getAttributes();
-
-    	/**
-    	 * Returns the target breakpoint context.  May be <code>null</code> if the 
-    	 * breakpoint failed to install on target. 
-    	 */
-    	public IBreakpointDMContext getTargetBreakpoint();
-
-    	/**
-    	 * Returns the status result of the last breakpoint operation (install/remove). 
-    	 */
-    	public IStatus getStatus();
-    }
+	
     
-    private static class TargetBP implements ITargetBreakpointInfo {
-    	
-    	private Map<String, Object> fAttributes;
-    	private IBreakpointDMContext fTargetBPContext;
-    	private IStatus fStatus;
-    	
-    	public TargetBP(Map<String, Object> attrs) {
-    		fAttributes = attrs;
-    	}
-    	
-    	public Map<String, Object> getAttributes() {
-			return fAttributes;
-		}
-    	
-    	public IBreakpointDMContext getTargetBreakpoint() {
-			return fTargetBPContext;
-		}
-    	
-    	public IStatus getStatus() {
-			return fStatus;
-		}
-
-		public void setTargetBreakpoint(IBreakpointDMContext fTargetBPContext) {
-			this.fTargetBPContext = fTargetBPContext;
-		}
-
-		public void setStatus(IStatus status) {
-			this.fStatus = status;
-		}
-    }
-    
-	private class PlatformBreakpointInfo {
-		IBreakpoint 		breakpoint;
-		boolean 			enabled;
-		// All attributes available from UI, including standard and extended ones.
-		Map<String, Object>	attributes;
-		
-		public PlatformBreakpointInfo(IBreakpoint bp, boolean enabled, Map<String, Object> attributes) {
-			super();
-			breakpoint = bp;
-			this.enabled = enabled;
-			this.attributes = attributes;
-		}
-	}
-
-	///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
     // Breakpoints tracking
     ///////////////////////////////////////////////////////////////////////////
 
     /**
-     * Holds the set of platform breakpoints with their breakpoint information 
-     * structures, per context (i.e. each platform breakpoint is
+     * Holds the set of platform breakpoints with their corresponding back-end
+     * breakpoint attributes, per context (i.e. each platform breakpoint is
      * replicated for each execution context).
      * - Context entry added/removed on start/stopTrackingBreakpoints()
      * - Augmented on breakpointAdded()
      * - Modified on breakpointChanged()
      * - Diminished on breakpointRemoved()
      */
-	private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<TargetBP>>> fPlatformBPs = 
-		new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<TargetBP>>>();
+	private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<Map<String, Object>>>> fPlatformBPs = 
+		new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<Map<String, Object>>>>();
 
-	/**
-	 * Holds platform breakpoints with all their attributes (standard ones and
-	 * extended ones) from UI. This will be used to check what attributes have
-	 * changed for a breakpoint when the breakpoint is changed. The map is <br>
-	 * 1. augmented in doBreakpointsAdded(); <br>
-	 * 2. updated in breakpointsChanged(); <br>
-	 * 3. diminished in breakpointsRemoved();
-	 */
-	private Map<IBreakpoint, Map<String, Object>> fBreakpointAttributes = 
-		new HashMap<IBreakpoint, Map<String, Object>>();
-	
-	private static class PendingEventInfo {
-		PendingEventInfo(BreakpointEventType eventType, PlatformBreakpointInfo bpInfo,
-				Collection<IBreakpointsTargetDMContext> bpsTargetDmc, RequestMonitor rm) {
-			fEventType = eventType;
-			fBPInfo = bpInfo;
-			fBPTargetContexts = bpsTargetDmc;
-			fRequestMonitor = rm;
-			fAttributeDelta = null;
-		}
-		
-		public PendingEventInfo(BreakpointEventType eventType, Collection<IBreakpointsTargetDMContext> updateContexts,
-				Map<String, Object> attrDelta) {
-			fEventType = eventType;
-			fBPTargetContexts = updateContexts;
-			fAttributeDelta = attrDelta;
-			fRequestMonitor = null;
-			fBPInfo = null;
-		}
+    /**
+     * Holds the mapping from platform breakpoint to the corresponding target
+     * breakpoint(s), per context. There can be multiple back-end BPs for a 
+     * single platform BP in the case of [1] multiple target contexts, and/or
+     * [2] thread filtering.
+     * Updated when:
+     * - We start/stop tracking an execution context
+     * - A platform breakpoint is added/removed
+     * - A thread filter is applied/removed
+     */
+	private Map<IBreakpointsTargetDMContext, Map<IBreakpoint, List<IBreakpointDMContext>>> fBreakpointDMContexts = 
+		new HashMap<IBreakpointsTargetDMContext, Map<IBreakpoint, List<IBreakpointDMContext>>>();
 
-		PlatformBreakpointInfo fBPInfo;
-		RequestMonitor fRequestMonitor;
-		BreakpointEventType fEventType;
-		Collection<IBreakpointsTargetDMContext> fBPTargetContexts;
-		Map<String, Object>	fAttributeDelta;	// for change event only
-	}
-	
     /**
      * Due to the very asynchronous nature of DSF, a new breakpoint request can
      * pop up at any time before an ongoing one is completed. The following set
      * is used to store requests until the ongoing operation completes.
      */
-	private Set<IBreakpoint> fRunningEvents    = new HashSet<IBreakpoint>();
-
-	private Map<IBreakpoint, LinkedList<PendingEventInfo>> fPendingEvents = 
-			new HashMap<IBreakpoint, LinkedList<PendingEventInfo>>();
+	private Set<IBreakpoint> fPendingRequests    = new HashSet<IBreakpoint>();
+	
+	/**
+	 * @see fPendingRequests
+	 */
+	private Set<IBreakpoint> fPendingBreakpoints = new HashSet<IBreakpoint>();
 	
     ///////////////////////////////////////////////////////////////////////////
     // AbstractDsfService    
@@ -228,10 +125,6 @@
 	public BreakpointsMediator(DsfSession session, IBreakpointAttributeTranslator attributeTranslator) {
         super(session);
         fAttributeTranslator = attributeTranslator;
-        
-        fAttributeTranslator2 = null;
-        if (attributeTranslator instanceof IBreakpointAttributeTranslatorExtension)
-        	fAttributeTranslator2 = (IBreakpointAttributeTranslatorExtension)attributeTranslator;
 	}
 
     @Override
@@ -256,7 +149,7 @@
     private void doInitialize(RequestMonitor rm) {
     	
     	// Get the services references
-        fBreakpointsService  = getServicesTracker().getService(IBreakpoints.class);
+        fBreakpoints  = getServicesTracker().getService(IBreakpoints.class);
         fBreakpointManager = DebugPlugin.getDefault().getBreakpointManager();
         fAttributeTranslator.initialize(this);
 
@@ -324,12 +217,20 @@
      * @param dmc Context to start tracking breakpoints for.
      * @param rm Completion callback.
      */
-    public void startTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) {
+    public void startTrackingBreakpoints(IBreakpointsTargetDMContext dmc, final RequestMonitor rm) {
         // - Augment the maps with the new execution context
         // - Install the platform breakpoints on the selected target
+
+    	// Validate the context
+        final IBreakpointsTargetDMContext breakpointsDmc = DMContexts.getAncestorOfType(dmc, IBreakpointsTargetDMContext.class);
+        if (breakpointsDmc == null) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context type", null)); //$NON-NLS-1$
+            rm.done();            
+            return;
+        }
             
         // Make sure a mapping for this execution context does not already exist
-		Map<IBreakpoint, List<TargetBP>> platformBPs = fPlatformBPs.get(dmc);
+		Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc);
 		if (platformBPs != null) {
             rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Context already initialized", null)); //$NON-NLS-1$
             rm.done();            
@@ -338,7 +239,8 @@
 
         // Create entries in the breakpoint tables for the new context. These entries should only
         // be removed when this service stops tracking breakpoints for the given context.
-        fPlatformBPs.put(dmc, new HashMap<IBreakpoint, List<TargetBP>>());
+        fPlatformBPs.put(breakpointsDmc, new HashMap<IBreakpoint, List<Map<String, Object>>>());
+		fBreakpointDMContexts.put(breakpointsDmc, new HashMap<IBreakpoint, List<IBreakpointDMContext>>());
 
         // Install the platform breakpoints (stored in fPlatformBPs) on the target.
 		// We need to use a background thread for this operation because we are 
@@ -346,142 +248,165 @@
 		// Accessing the resources system potentially requires using global locks.
 		// Also we will be calling IBreakpointAttributeTranslator which is prohibited
 		// from being called on the session executor thread.
-		new Job("Install initial breakpoint list.") { //$NON-NLS-1$
-            { setSystem(true); }
-
-			// Get the stored breakpoints from the platform BreakpointManager
-			// and install them on the target
-        	@Override
-            protected IStatus run(IProgressMonitor monitor) {
-        		doBreakpointsAdded(DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(), dmc, rm);
-                return Status.OK_STATUS;
-            }
-        }.schedule();    
-    }
-
-    public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) {
-        // - Remove the target breakpoints for the given execution context
-        // - Update the maps
-
-    	// Remove the breakpoints for given DMC from the internal maps.
-        Map<IBreakpoint, List<TargetBP>> platformBPs = fPlatformBPs.get(dmc);
-        if (platformBPs == null || platformBPs.size() == 0) {
-            rm.setStatus(new Status(IStatus.INFO /* NOT error */, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Breakpoints not installed for given context", null)); //$NON-NLS-1$
-            rm.done();
-            return;
-        }
-        
-        // Just remove the IBreakpoints installed for the "dmc".
-        final IBreakpoint[] bps = platformBPs.keySet().toArray(new IBreakpoint[platformBPs.size()]);
-        
-		new Job("Uninstall target breakpoints list.") { //$NON-NLS-1$
+		new Job("MI Debugger: Install initial breakpoint list.") { //$NON-NLS-1$
             { setSystem(true); }
 
 			// Get the stored breakpoints from the platform BreakpointManager
 			// and install them on the target
         	@Override
             protected IStatus run(IProgressMonitor monitor) {
-        		doBreakpointsRemoved(bps, dmc, rm);
+                // Read initial breakpoints from platform.  Copy the breakpoint attributes into a local map.
+                // Note that we cannot write data into fPlatformBPs table here directly because we are not
+                // executing on the dispatch thread.
+                final Map<IBreakpoint, List<Map<String, Object>>> initialPlatformBPs = 
+                    new HashMap<IBreakpoint, List<Map<String, Object>>>();
+                try {
+                	// Get the stored breakpoint list from the platform BreakpointManager
+                    IBreakpoint[] bps = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
+                    // Single out the installable breakpoints...
+                    for (IBreakpoint bp : bps) {
+                    	if (fAttributeTranslator.supportsBreakpoint(bp)) {
+	                        // Retrieve the breakpoint attributes
+                    		List<Map<String, Object>> attrsArray = 
+                    		    fAttributeTranslator.getBreakpointAttributes(bp, fBreakpointManager.isEnabled());
+	                        // Store it for now (will be installed on the dispatcher thread)
+                            initialPlatformBPs.put(bp, attrsArray);
+                        }
+                    }
+                } catch (CoreException e) {
+                    IStatus status = new Status(
+                        IStatus.ERROR, DsfPlugin.PLUGIN_ID, REQUEST_FAILED, "Unable to read initial breakpoint attributes", e); //$NON-NLS-1$
+                    rm.setStatus(status);
+                    rm.done();
+                    return status;
+                }
+                
+                // Submit the runnable to plant the breakpoints on dispatch thread.
+                getExecutor().submit(new Runnable() {
+                	public void run() {
+                		installInitialBreakpoints(breakpointsDmc, initialPlatformBPs, rm);
+                	}
+                });
+
                 return Status.OK_STATUS;
             }
         }.schedule();    
     }
-    
-    /**
-     * Find target breakpoints installed in the given context that are resolved 
-     * from the given platform breakpoint.
-     *  
-     * @param dmc - context
-     * @param platformBp - platform breakpoint
-     * @return array of target breakpoints. 
-     */
-    public ITargetBreakpointInfo[] getTargetBreakpoints(IBreakpointsTargetDMContext dmc, IBreakpoint platformBp) {
-    	assert getExecutor().isInExecutorThread();
-    	
-        Map<IBreakpoint, List<TargetBP>> platformBPs = fPlatformBPs.get(dmc);
 
-        if (platformBPs != null)
-        {
-        	List<TargetBP> bpInfo = platformBPs.get(platformBp);
-            if (bpInfo != null) {
-            	return bpInfo.toArray(new ITargetBreakpointInfo[bpInfo.size()]);
-            }
-        }
-        return null;
-    }
-    
     /**
-     * Find the platform breakpoint that's mapped to the given target breakpoint.
-     * 
-     * @param dmc - context of the target breakpoint, can be null.
-     * @param bp - target breakpoint
-     * @return platform breakpoint. null if not found. 
+     * Installs the breakpoints that existed prior to the activation of this
+     * breakpoints context.
      */
-    public IBreakpoint getPlatformBreakpoint(IBreakpointsTargetDMContext dmc, IBreakpointDMContext bp) {
-    	assert getExecutor().isInExecutorThread();
+    private void installInitialBreakpoints(final IBreakpointsTargetDMContext dmc,
+            Map<IBreakpoint, List<Map<String, Object>>> initialPlatformBPs,
+            RequestMonitor rm)
+    {
+        // Retrieve the set of platform breakpoints for this context
+        Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc);
+        if (platformBPs == null) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
+            rm.done();
+            return;
+        }
+
+        // Install the individual breakpoints on the executor thread
+        // Requires a counting monitor to know when we're done
+        final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm);
+        countingRm.setDoneCount(initialPlatformBPs.size());
+
+        for (final IBreakpoint bp : initialPlatformBPs.keySet()) {
+            final List<Map<String, Object>> attrs = initialPlatformBPs.get(bp);
+            // Upon determining the debuggerPath, the breakpoint is installed
+            installBreakpoint(dmc, bp, attrs, new RequestMonitor(getExecutor(), countingRm));
+        }
+    }
+
+    
+    public void stopTrackingBreakpoints(final IBreakpointsTargetDMContext dmc, final RequestMonitor rm) {
+        // - Remove the target breakpoints for the given execution context
+        // - Update the maps
 
-    	for (IBreakpointsTargetDMContext bpContext : fPlatformBPs.keySet()) {
-    		if (dmc != null && !dmc.equals(bpContext))
-    			continue;
-    		
-	        Map<IBreakpoint, List<TargetBP>> platformBPs = fPlatformBPs.get(bpContext);
-	
-	        if (platformBPs != null && platformBPs.size() > 0)
-	        {
-	            for(Map.Entry<IBreakpoint, List<TargetBP>> e: platformBPs.entrySet())
-	            {
-	                // Stop at the first occurrence
-	            	for (TargetBP tbp : e.getValue())
-	            		if(tbp.getTargetBreakpoint().equals(bp))
-	            			return e.getKey();
-	            }    
-	        }
-    	}
+    	// Remove the breakpoints for given DMC from the internal maps.
+        Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc);
+        if (platformBPs == null) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INTERNAL_ERROR, "Breakpoints not installed for given context", null)); //$NON-NLS-1$
+            rm.done();
+            return;
+        }
+
+        // Uninstall the individual breakpoints on the executor thread
+        // Requires a counting monitor to know when we're done
+        final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm);
+        countingRm.setDoneCount(platformBPs.size());
 
-    	return null;
+        for (final IBreakpoint bp : platformBPs.keySet()) {
+            uninstallBreakpoint(dmc, bp, 
+                new RequestMonitor(getExecutor(), countingRm) {
+                    @Override
+                    protected void handleCompleted() {
+                        // After the breakpoint is removed from target.  Call the attribute 
+                        // translator to refresh breakpoint status based on the new target 
+                        // breakpoint status. 
+                        new Job("Breakpoint status update") { //$NON-NLS-1$
+                            { setSystem(true); }
+                            @Override
+                            protected IStatus run(IProgressMonitor monitor) {
+                                fAttributeTranslator.updateBreakpointStatus(bp);
+                                return Status.OK_STATUS;
+                            };
+                        }.schedule();
+
+                        countingRm.done();
+                    }
+                });
+        }
     }
-    
+
     ///////////////////////////////////////////////////////////////////////////
     // Back-end interface functions
     ///////////////////////////////////////////////////////////////////////////
 
 	/**
 	 * Install a new platform breakpoint on the back-end. A platform breakpoint
-	 * can resolve into multiple back-end breakpoints, e.g. when threads are taken
+	 * can resolve into multiple back-end breakpoints when threads are taken
 	 * into account.
 	 *  
 	 * @param dmc
 	 * @param breakpoint
-	 * @param attrsList - list of attribute map, each mapping to a potential target BP.
+	 * @param attrsList
 	 * @param rm
 	 */
 	private void installBreakpoint(IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint,
-			final List<Map<String, Object>> attrsList, final DataRequestMonitor<List<TargetBP>> rm)
+			final List<Map<String, Object>> attrsList, final RequestMonitor rm)
 	{
     	// Retrieve the set of breakpoints for this context
-        final Map<IBreakpoint, List<TargetBP>> platformBPs = fPlatformBPs.get(dmc);
+        final Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc);
         assert platformBPs != null;
 
+        final Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc);
+        assert breakpointIDs != null; // fBreakpointIds should be updated in parallel with fPlatformBPs 
+
         // Ensure the breakpoint is not already installed
-        assert !platformBPs.containsKey(breakpoint);
-
-        final ArrayList<TargetBP> targetBPsAttempted = new ArrayList<TargetBP>(attrsList.size());
-        for (int i = 0; i < attrsList.size(); i++) {
-        	targetBPsAttempted.add(new TargetBP(attrsList.get(i)));
+        if (platformBPs.containsKey(breakpoint)) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_STATE, "Breakpoint already installed", null)); //$NON-NLS-1$
+            rm.done();
+            return;
         }
-        
-        final ArrayList<TargetBP> targetBPsInstalled = new ArrayList<TargetBP>(attrsList.size());
 
         // Update the breakpoint status when all back-end breakpoints have been installed
     	final CountingRequestMonitor installRM = new CountingRequestMonitor(getExecutor(), rm) {
 			@Override
 			protected void handleCompleted() {
-				// Store successful targetBPs with the platform breakpoint
-				if (targetBPsInstalled.size() > 0)
-					platformBPs.put(breakpoint, targetBPsInstalled);
-				
-				// Store all targetBPs, success or failure, in the rm.
-				rm.setData(targetBPsAttempted);
+				// Store the platform breakpoint
+				platformBPs.put(breakpoint, attrsList);
+                new Job("Breakpoint status update") { //$NON-NLS-1$
+                    { setSystem(true); }
+                    @Override
+                    protected IStatus run(IProgressMonitor monitor) {
+                        fAttributeTranslator.updateBreakpointStatus(breakpoint);
+                        return Status.OK_STATUS;
+                    };
+                }.schedule();
 		        rm.done();
 			}
 		};
@@ -490,22 +415,25 @@
 		installRM.setDoneCount(attrsList.size());
 
 		// Install the back-end breakpoint(s)
-		for (int _i = 0; _i < attrsList.size(); _i++) {
-			final int i = _i;
-            fBreakpointsService.insertBreakpoint(
-                dmc, attrsList.get(i), 
+		for (Map<String, Object> attrs : attrsList) {
+            fBreakpoints.insertBreakpoint(
+                dmc, attrs, 
 				new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), installRM) {
 				@Override
                 protected void handleCompleted() {
-					TargetBP targetBP = targetBPsAttempted.get(i);
+                    List<IBreakpointDMContext> list = breakpointIDs.get(breakpoint);
+                    if (list == null) {
+                        list = new LinkedList<IBreakpointDMContext>();
+                        breakpointIDs.put(breakpoint, list);
+                    }
+                    
                     if (isSuccess()) {
 						// Add the breakpoint back-end mapping
-                    	targetBP.setTargetBreakpoint(getData());
-                    	
-                    	targetBPsInstalled.add(targetBP);
-					} 
-                    targetBP.setStatus(getStatus());
-                    
+						list.add(getData());
+					} else {
+                        // TODO (bug 219841): need to add breakpoint error status tracking
+                        // in addition to fBreakpointDMContexts.
+					}
 					installRM.done();
                 }
             });
@@ -518,612 +446,441 @@
      * 
      * @param dmc
      * @param breakpoint
-     * @param drm
+     * @param rm
      */
     private void uninstallBreakpoint(final IBreakpointsTargetDMContext dmc, final IBreakpoint breakpoint, 
-        final DataRequestMonitor<List<TargetBP>> drm)
+        final RequestMonitor rm)
     {
+  		// Remove completion monitor
+    	CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) {
+			@Override
+			protected void handleCompleted() {
+		    	// Remove the attributes mapping 
+		        Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(dmc);
+		        if (platformBPs == null) {
+		            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
+		            rm.done();
+		            return;
+		        }
+		        platformBPs.remove(breakpoint);
+
+				// Remove the back-end mapping
+		        Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc);
+		        if (breakpointIDs == null) {
+		            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$
+		            rm.done();
+		            return;
+		        }
+		        breakpointIDs.get(breakpoint).clear();
+		        breakpointIDs.remove(breakpoint);
+
+		        // Update breakpoint status
+                new Job("Breakpoint status update") { //$NON-NLS-1$
+                    { setSystem(true); }
+                    @Override
+                    protected IStatus run(IProgressMonitor monitor) {
+                        fAttributeTranslator.updateBreakpointStatus(breakpoint);
+                        return Status.OK_STATUS;
+                    };
+                }.schedule();
+
+		        rm.done();
+			}
+		};
+
 		// Remove the back-end breakpoints
-		final Map<IBreakpoint, List<TargetBP>> platformBPs = fPlatformBPs.get(dmc);
-        if (platformBPs == null) {
-            drm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$
-            drm.done();
+		Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(dmc);
+        if (breakpointIDs == null) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$
+            rm.done();
+            return;
+        }
+
+        List<IBreakpointDMContext> list = breakpointIDs.get(breakpoint);
+        int count = 0;
+        if (list != null) {
+            for (IBreakpointDMContext bp : list) {
+                fBreakpoints.removeBreakpoint(bp, removeRM);
+            }
+            count = list.size();
+        }
+        removeRM.setDoneCount(count);
+    }
+	
+	/**
+	 * Modify an individual breakpoint
+	 * 
+	 * @param context
+	 * @param breakpoint
+	 * @param attributes
+	 * @param rm
+	 * @throws CoreException
+	 */
+	private void modifyBreakpoint(final IBreakpointsTargetDMContext context, final IBreakpoint breakpoint,
+			final List<Map<String, Object>> newAttrsList0, final IMarkerDelta oldValues, final RequestMonitor rm)
+	{
+	    // This method uses several lists to track the changed breakpoints:
+	    // commonAttrsList - attributes which have not changed 
+	    // oldAttrsList - attributes for the breakpoint before the change
+	    // newAttrsList - attributes for the breakpoint after the change
+	    // oldBpContexts - target-side breakpoints from before the change
+	    // newBpContexts - target-side breakpoints after the change
+	    // attrDeltasList - changes in the attributes for each attribute map in 
+	    //     oldAttrsList and newAttrsList
+	    
+    	// Get the maps
+        final Map<IBreakpoint, List<Map<String, Object>>> platformBPs = fPlatformBPs.get(context);
+        final Map<IBreakpoint, List<IBreakpointDMContext>> breakpointIDs = fBreakpointDMContexts.get(context);
+        if (platformBPs == null || breakpointIDs == null) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context", null)); //$NON-NLS-1$
+            rm.done();
+            return;
+        }
+
+    	// Get the original breakpoint attributes
+        final List<Map<String, Object>> oldAttrsList0 = platformBPs.get(breakpoint);
+        if (oldAttrsList0 == null) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$
+            rm.done();
+            return;
+        }
+
+        // Get the list of corresponding back-end breakpoints 
+        final List<IBreakpointDMContext> oldBpContexts = new ArrayList<IBreakpointDMContext>(breakpointIDs.get(breakpoint));
+        if (oldBpContexts == null) {
+            rm.setStatus(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid breakpoint", null)); //$NON-NLS-1$
+            rm.done();
             return;
         }
 
-        final List<TargetBP> bpList = platformBPs.get(breakpoint);
-        assert bpList != null;
-
-        // Only try to remove those targetBPs that are successfully installed.
-        
-  		// Remove completion monitor
-    	final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), drm) {
-			@Override
-			protected void handleCompleted() {
-				platformBPs.remove(breakpoint);
-
-		        // Complete the request monitor.
-		        drm.setData(bpList);
-		        drm.done();
-			}
-		};
+        // Calculate the list of attributes maps that have not changed.  
+        // Immediately add these to the list of new breakpoint contexts,
+        // and remove them from further breakpoint attribute comparisons.
+        final List<Map<String, Object>> commonAttrsList = getCommonAttributeMaps(newAttrsList0, oldAttrsList0);
+        final List<IBreakpointDMContext> newBpContexts = new ArrayList<IBreakpointDMContext>(commonAttrsList.size());
 
-        int count = 0;
-        for (int i = 0; i < bpList.size(); i++) {
-        	final TargetBP bp = bpList.get(i);
-        	if (bp.getTargetBreakpoint() != null) {
-        		fBreakpointsService.removeBreakpoint(
-        				bp.getTargetBreakpoint(), 
-        				new RequestMonitor(getExecutor(), countingRm) {
-        					@Override
-        					protected void handleCompleted() {
-        				        bp.setStatus(getStatus());
-        				        if (isSuccess()) {
-            						bp.setTargetBreakpoint(null);
-        				        } 
-        				        countingRm.done();
-        					}
-        				});
-        		count++;
-        	} else {
-        		bp.setStatus(Status.OK_STATUS);
-        	}
+        final List<Map<String, Object>> newAttrsList = new ArrayList<Map<String, Object>>(newAttrsList0);
+        newAttrsList.removeAll(commonAttrsList);
+        
+        List<Map<String, Object>> oldAttrsList = new ArrayList<Map<String, Object>>(oldAttrsList0);
+        for (int i = 0; i < oldAttrsList.size(); i++) {
+            if (commonAttrsList.contains(oldAttrsList.get(i))) {
+                if (oldBpContexts.size() > i) {
+                    newBpContexts.add(oldBpContexts.remove(i));
+                }
+            }
         }
-        countingRm.setDoneCount(count);
-    }
+        oldAttrsList.removeAll(commonAttrsList);
+        
+        // Create a list of attribute changes.  The lenghth of this list will
+        // always be max(oldAttrList.size(), newAttrsList.size()), padded with
+        // null's if oldAttrsList was longer.
+        final List<Map<String, Object>> attrDeltasList = getAttributesDeltas(oldAttrsList, newAttrsList);
+        
+        // Create the request monitor that will be called when all
+        // modifying/inserting/removing is complete.
+        final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm) {
+            @Override
+            protected void handleCompleted() {
+                // Save the new list of breakpoint contexts and attributes 
+                breakpointIDs.put(breakpoint, newBpContexts);
+                newAttrsList.addAll(commonAttrsList);
+                platformBPs.put(breakpoint, newAttrsList);
+                
+                // Update breakpoint status.  updateBreakpointStatus() cannot
+                // be called on the executor thread, so we need to 
+                // use a Job.
+                new Job("Breakpoint status update") { //$NON-NLS-1$
+                    { setSystem(true); }
+                    @Override
+                    protected IStatus run(IProgressMonitor monitor) {
+                        fAttributeTranslator.updateBreakpointStatus(breakpoint);
+                        return Status.OK_STATUS;
+                    };
+                }.schedule();
+                
+                super.handleCompleted();
+            }
+        };
+        
+        // Set the count, if could be zero if no breakpoints have actually changed.
+        countingRM.setDoneCount(attrDeltasList.size());
+        
+        // Process the changed breakpoints.
+        for (int i = 0; i < attrDeltasList.size(); i++) {
+            if (attrDeltasList.get(i) == null) {
+                // The list of new attribute maps was shorter than the old.
+                // Remove the corresponding target-side bp.
+                fBreakpoints.removeBreakpoint(oldBpContexts.get(i), countingRM);
+            } else if ( i >= oldBpContexts.size()) {
+                // The list of new attribute maps was longer, just insert
+                // the new breakpoint
+                final Map<String, Object> attrs = newAttrsList.get(i);
+                fBreakpoints.insertBreakpoint(
+                    context, attrs, 
+                    new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), countingRM) {
+                        @Override
+                        protected void handleSuccess() {
+                            newBpContexts.add(getData());
+                            countingRM.done();
+                        }
+                    });
+            } else if ( !fAttributeTranslator.canUpdateAttributes(oldBpContexts.get(i), attrDeltasList.get(i)) ) {
+                // The attribute translator tells us that the debugger cannot modify the 
+                // breakpoint to change the given attributes.  Remove the breakpoint
+                // and insert a new one.
+                final Map<String, Object> attrs = newAttrsList.get(i);
+                fBreakpoints.removeBreakpoint(
+                    oldBpContexts.get(i), 
+                    new RequestMonitor(getExecutor(), countingRM) {
+                        @Override
+                        protected void handleCompleted() {
+                            fBreakpoints.insertBreakpoint(
+                                context, attrs,
+                                new DataRequestMonitor<IBreakpointDMContext>(getExecutor(), countingRM) {
+                                    @Override
+                                    protected void handleCompleted() {
+                                        if (isSuccess()) { 
+                                            newBpContexts.add(getData());
+                                        } else {
+                                            // TODO (bug 219841): need to add breakpoint error status tracking
+                                            // in addition to fBreakpointDMContexts.
+                                        }
+                                        countingRM.done();
+                                    }
+                                });
+                        }
+                    });
+            } else {
+                // The back end can modify the breakpoint.  Update the breakpoint with the 
+                // new attributes.
+                final IBreakpointDMContext bpCtx = oldBpContexts.get(i); 
+                fBreakpoints.updateBreakpoint(
+                    oldBpContexts.get(i), newAttrsList.get(i), 
+                    new RequestMonitor(getExecutor(), countingRM) {
+                        @Override
+                        protected void handleSuccess() {
+                            newBpContexts.add(bpCtx);
+                            countingRM.done();
+                        }
+                    });
+            }
+        }
+	} 
 	
+	private List<Map<String, Object>> getCommonAttributeMaps(List<Map<String, Object>> array1, List<Map<String, Object>> array2) 
+	{
+	    List<Map<String, Object>> intersection = new LinkedList<Map<String, Object>>();
+	    List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>(array2);
+	    for (Map<String, Object> array1Map : array1) {
+	        if (list2.remove(array1Map)) {
+	            intersection.add(array1Map);
+	        }
+	    }
+	    return intersection;
+	}
+	
+	/**
+	 * Determine the set of modified attributes
+	 * 
+	 * @param oldAttributes
+	 * @param newAttributes
+	 * @return
+	 */
+	private List<Map<String, Object>> getAttributesDeltas(List<Map<String, Object>> oldAttributesList, List<Map<String, Object>> newAttributesList) {
+	    List<Map<String, Object>> deltas = new ArrayList<Map<String, Object>>(oldAttributesList.size());
+	    
+	    // Go through the bp attributes common to the old and the new lists and calculate
+	    // their deltas.
+	    for (int i = 0; i < oldAttributesList.size() && i < newAttributesList.size(); i++) {
+	        Map<String, Object> oldAttributes = oldAttributesList.get(i); 
+	        Map<String, Object> newAttributes = newAttributesList.get(i);
+    	    
+	        Map<String, Object> delta = new HashMap<String, Object>();
+    
+    		Set<String> oldKeySet = oldAttributes.keySet();		
+    		Set<String> newKeySet = newAttributes.keySet();
+    
+    		Set<String> commonKeys  = new HashSet<String>(newKeySet); commonKeys.retainAll(oldKeySet);
+    		Set<String> addedKeys   = new HashSet<String>(newKeySet); addedKeys.removeAll(oldKeySet);
+    		Set<String> removedKeys = new HashSet<String>(oldKeySet); removedKeys.removeAll(newKeySet);
+    
+    		// Add the modified attributes
+    		for (String key : commonKeys) {
+    			if (!(oldAttributes.get(key).equals(newAttributes.get(key))))
+    				delta.put(key, newAttributes.get(key));
+    		}
+    
+    		// Add the new attributes
+    		for (String key : addedKeys) {
+    			delta.put(key, newAttributes.get(key));
+    		}
+    
+    		// Remove the deleted attributes
+    		for (String key : removedKeys) {
+    			delta.put(key, null);
+    		}
+    		deltas.add(delta);
+	    } 
+	    
+	    // Add all the new attributes as deltas
+	    for (int i = deltas.size(); i < newAttributesList.size(); i++) {
+	        deltas.add(newAttributesList.get(i));
+	    }
+	    
+        // For any old attribute Maps that were removed, insert a null value in the deltas list.
+        for (int i = deltas.size(); i < oldAttributesList.size(); i++) {
+            deltas.add(null);
+        }
+	    
+	    return deltas;
+	}
+
     ///////////////////////////////////////////////////////////////////////////
     // IBreakpointManagerListener implementation
     ///////////////////////////////////////////////////////////////////////////
 
 	public void breakpointManagerEnablementChanged(boolean enabled) {
-		// do nothing. breakpointsChanged() will be called to handle the change.
+		for (IBreakpoint breakpoint : fBreakpointManager.getBreakpoints()) {
+		    breakpointChanged(breakpoint, null);
+		}
 	}
 
 	@ThreadSafe
-	public void breakpointsAdded(final IBreakpoint[] bps) {
-		doBreakpointsAdded(bps, null, null);
-	}
-	
-	protected void doBreakpointsAdded(final IBreakpoint[] bps, final IBreakpointsTargetDMContext bpsTargetDmc, final RequestMonitor rm) {
-		// Collect attributes (which will access system resource)
-		// in non DSF dispatch thread.
-		//
-		final PlatformBreakpointInfo[] bpsInfo = collectBreakpointsInfo(bps);
-		
-		// Nothing to do
-		if (bpsInfo.length == 0) {
-			if (rm != null) {
-				rm.done();
-			}
-			return;
-		}
-
-		try {
-            getExecutor().execute(new DsfRunnable() {
-				public void run() {
-					Collection<IBreakpointsTargetDMContext> dmcs = new ArrayList<IBreakpointsTargetDMContext>();
-					if (bpsTargetDmc == null)
-						dmcs.addAll(fPlatformBPs.keySet());
-					else
-						dmcs.add(bpsTargetDmc);
+	public void breakpointAdded(final IBreakpoint breakpoint) {
+		if (fAttributeTranslator.supportsBreakpoint(breakpoint)) {
+			try {
+                // Retrieve the breakpoint attributes
+        		final List<Map<String, Object>> attrsArray = 
+                    fAttributeTranslator.getBreakpointAttributes(breakpoint, fBreakpointManager.isEnabled());
 
-					doBreakpointsAddedInExecutor(bpsInfo, dmcs, rm);
-				}
-			});
-		} catch (RejectedExecutionException e) {
-			IStatus status = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e);//$NON-NLS-1$ //$NON-NLS-2$
-			if (rm != null) {
-				rm.setStatus(status);
-				rm.done();
-			} else {
-				DsfPlugin.getDefault().getLog().log(status); 
-			}
-		}
-	}
-	
-	/**
-	 * Collect breakpoint info. This method must not be called in DSF dispatch thread.
-	 * @param bps
-	 * @return
-	 */
-    private PlatformBreakpointInfo[] collectBreakpointsInfo(IBreakpoint[] bps) {
-		List<PlatformBreakpointInfo> bpsInfo = new ArrayList<PlatformBreakpointInfo>(bps.length);
-		
-		for (IBreakpoint bp : bps) {
-			if (bp.getMarker() == null)
-				continue;
-			
-			if (fAttributeTranslator.supportsBreakpoint(bp)) {
-				try {
-	        		Map<String, Object> attrs = fAttributeTranslator2.getAllBreakpointAttributes(bp, fBreakpointManager.isEnabled());
-	        		boolean enabled = bp.isEnabled() && fBreakpointManager.isEnabled();
-					bpsInfo.add(new PlatformBreakpointInfo(bp, enabled, attrs));
-				} catch (CoreException e) {
-					DsfPlugin.getDefault().getLog().log(e.getStatus());
-				}
+                getExecutor().execute(new DsfRunnable() {
+					public void run() {
+					    //TODO pp: need to track pending requests 
+					    
+						final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) {
+							@Override
+							protected void handleError() {
+								if (getStatus().getSeverity() == IStatus.ERROR) {
+									DsfPlugin.getDefault().getLog().log(getStatus());
+								}
+							}
+						};
+						countingRm.setDoneCount(fPlatformBPs.size());
+
+						// Install the breakpoint in all the execution contexts
+						for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
+						    installBreakpoint(dmc, breakpoint, attrsArray, new RequestMonitor(getExecutor(), countingRm));
+						}
+					}
+				});
+			} catch (CoreException e) {
+                DsfPlugin.getDefault().getLog().log(e.getStatus());
+			} catch (RejectedExecutionException e) {
 			}
 		}
-		
-		return bpsInfo.toArray(new PlatformBreakpointInfo[bpsInfo.size()]);
-	}
 
-	protected void doBreakpointsAddedInExecutor(PlatformBreakpointInfo[] bpsInfo, Collection<IBreakpointsTargetDMContext> bpTargetDMCs, final RequestMonitor rm) {
-		final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs =  
-			new HashMap<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>>(bpsInfo.length, 1);
-		
-        CountingRequestMonitor processPendingCountingRm = new CountingRequestMonitor(getExecutor(), rm) {
-                @Override
-                protected void handleCompleted() {
-                	processPendingRequests();
-                	fireUpdateBreakpointsStatus(eventBPs, BreakpointEventType.ADDED);
-                	if (rm != null)
-                		// don't call this if "rm" is null as this will 
-                		// log errors if any and pack Eclipse error 
-                		// log view with errors useless to user. 
-                		super.handleCompleted();
-                }
-            };	            	
-        int processPendingCountingRmCount = 0;
-    	
-    	for (final PlatformBreakpointInfo bpinfo : bpsInfo) {
-    		final Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> targetBPs = 
-    			new HashMap<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>(fPlatformBPs.size(), 1);
-    		eventBPs.put(bpinfo.breakpoint, targetBPs);	
-    	
-			// Remember the new attributes of the bp in our global buffer,
-			// even if we cannot or fail to install the bp.
-			fBreakpointAttributes.put(bpinfo.breakpoint, bpinfo.attributes);
-    		
-			if (fRunningEvents.contains(bpinfo.breakpoint)) {
-				PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.ADDED, bpinfo, bpTargetDMCs, processPendingCountingRm);
-				processPendingCountingRmCount++;
-				updatePendingRequest(bpinfo.breakpoint, pendingEvent);
-				continue;
-			}
-			
-			processPendingCountingRmCount++;
-
-            // Mark the breakpoint as being updated and go
-            fRunningEvents.add(bpinfo.breakpoint);
-
-    		final CountingRequestMonitor bpTargetsCountingRm = new CountingRequestMonitor(getExecutor(), processPendingCountingRm) {
-				@Override
-				protected void handleCompleted() {
-                	// Indicate that the running event has completed
-                	fRunningEvents.remove(bpinfo.breakpoint);
-                	super.handleCompleted();
-				}
-    		};
-
-			int bpTargetsCountingRmCount = 0;
-
-			// Install the breakpoint in all the execution contexts
-			for (final IBreakpointsTargetDMContext dmc : bpTargetDMCs) {
-				
-                // Now ask lower level to set the bp.
-				//
-				// if the breakpoint is disabled, ask back-end if it can set (and manage)
-				// disabled breakpoint. If not, just bail out.
-				//
-				if (! bpinfo.enabled) {
-					Map<String, Object> attr = new HashMap<String, Object>(1);
-					attr.put(IBreakpoint.ENABLED, Boolean.FALSE);
-					Map<String, Object> targetEnablementAttr = fAttributeTranslator2.convertAttributes(attr);
-					if (! fAttributeTranslator2.canUpdateAttributes(bpinfo.breakpoint, dmc, targetEnablementAttr)) {
-						// bail out. Continue with the next dmc & breakpoint.
-						continue;
-					}
-				}
-            	
-				// Now do the real work.
-				//
-				fAttributeTranslator2.resolveBreakpoint(dmc, bpinfo.breakpoint, bpinfo.attributes,
-						new DataRequestMonitor<List<Map<String,Object>>>(getExecutor(), bpTargetsCountingRm){
-							@Override
-							protected void handleSuccess() {
-								installBreakpoint(
-							    		dmc, bpinfo.breakpoint, getData(), 
-							    		new DataRequestMonitor<List<TargetBP>>(getExecutor(), bpTargetsCountingRm) {
-							    			@Override
-											protected void handleSuccess() {
-							    				targetBPs.put(dmc, getData().toArray(new ITargetBreakpointInfo[getData().size()]));
-							    				super.handleSuccess();
-							    			};
-							    		});
-							}});
-				
-				bpTargetsCountingRmCount++;
-			}
-			
-			bpTargetsCountingRm.setDoneCount(bpTargetsCountingRmCount);
-    	}
-    	
-    	processPendingCountingRm.setDoneCount(processPendingCountingRmCount);	            	
 	}
+	
+    ///////////////////////////////////////////////////////////////////////////
+    // IBreakpointListener implementation
+    ///////////////////////////////////////////////////////////////////////////
 
-	/*
-	 * Note this method must not be called in DSF dispatch thread.
-	 * 
-	 * @param bps
-	 * @param deltas
-	 */
-	public void breakpointsChanged(IBreakpoint[] bps, IMarkerDelta[] deltas) {
-		if (fAttributeTranslator2 == null)
-			return;
-		
-		final PlatformBreakpointInfo[] bpsInfo = collectBreakpointsInfo(bps);
-		
-		if (bpsInfo.length == 0) 
-			return; // nothing to do
-		
-		try {
-	        getExecutor().execute( new DsfRunnable() { 
-	            public void run() {
-	            	Map<String, Object> tmp = new HashMap<String, Object>(1);
-					tmp.put(IBreakpoint.ENABLED, true);
-					final String targetEnablementKey = fAttributeTranslator2.convertAttributes(tmp).keySet().iterator().next();
+	public void breakpointChanged(final IBreakpoint breakpoint, final IMarkerDelta delta) {
+		if (fAttributeTranslator.supportsBreakpoint(breakpoint)) {
+			try {
+                // Retrieve the breakpoint attributes
+        		final List<Map<String, Object>> attrsArray = 
+        		    fAttributeTranslator.getBreakpointAttributes(breakpoint, fBreakpointManager.isEnabled());
+
+				// Modify the breakpoint in all the target contexts
+		        getExecutor().execute( new DsfRunnable() { 
+		            public void run() {
 
-					for (PlatformBreakpointInfo bpinfo : bpsInfo) {
-						/*
-						 * We cannot depend on "deltas" for attribute change.
-						 * For instance, delta can be null when extended
-						 * attributes (e.g. breakpoint thread filter for GDB)
-						 * are changed.
-						 */
-						Map<String, Object> newAttrs = bpinfo.attributes;
-						Map<String, Object> oldAttrs = fBreakpointAttributes.get(bpinfo.breakpoint);
-						
-						// remember the new attributes.
-						fBreakpointAttributes.put(bpinfo.breakpoint, newAttrs);
-						
-						final Map<String, Object> attrDelta = getAttributesDelta(oldAttrs, newAttrs);
-						if (attrDelta.size() == 0) 
-							continue;
+		            	// If the breakpoint is currently being updated, queue the request and exit
+		            	if (fPendingRequests.contains(breakpoint)) {
+		            		fPendingBreakpoints.add(breakpoint);
+							return;
+		            	}
+
+		                // Keep track of the updates
+		                final CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) {
+		                    @Override
+		                    protected void handleCompleted() {
+
+		                    	if (!isSuccess()) {
+			                        if (getStatus().getSeverity() == IStatus.ERROR) {
+			                            DsfPlugin.getDefault().getLog().log(getStatus());
+			                        }
+		                    	}
 
-						final List<IBreakpointsTargetDMContext> reinstallContexts = new ArrayList<IBreakpointsTargetDMContext>();
-						
-						List<IBreakpointsTargetDMContext> updateContexts = new ArrayList<IBreakpointsTargetDMContext>();
-						
-						// Now change the breakpoint for each known context.
-						//
-						for (final IBreakpointsTargetDMContext btContext : fPlatformBPs.keySet()) {
-							
-							if (! fAttributeTranslator2.canUpdateAttributes(bpinfo.breakpoint, btContext, attrDelta)) {
-								// backend cannot handle at least one of the platform BP attribute change,
-								// we'll handle the re-installation.
-								reinstallContexts.add(btContext);
-							}
-							else {
-								// Backend claims it can handle the attributes change, let it do it.
-								updateContexts.add(btContext);
-							}
-							
-						}
-
-						final PlatformBreakpointInfo[] oneBPInfo = new PlatformBreakpointInfo[] {bpinfo};
-						IBreakpoint[] oneBP = new IBreakpoint[] {bpinfo.breakpoint};
+		                    	// Indicate that the pending request has completed
+		                    	fPendingRequests.remove(breakpoint);
 
-						if (reinstallContexts.size() > 0) {
-							// Check if it's only enablement change (user click enable/disable 
-							// button or "Skip all breakpoints" button), which is common operation.
-							//
-							if (attrDelta.size() == 1 && attrDelta.containsKey(targetEnablementKey)) { // only enablement changed.	
-								if (bpinfo.enabled)  {
-									// change from disable to enable. Install the bp.
-									doBreakpointsAddedInExecutor(oneBPInfo, reinstallContexts, null);
-								}
-								else {
-									// change from enable to disable. Remove the bp.
-									doBreakpointsRemovedInExecutor(oneBP,  reinstallContexts, null);
-								}
-							}
-							else {
-								doBreakpointsRemovedInExecutor(oneBP, reinstallContexts, new RequestMonitor(getExecutor(), null) {
-									// What should we do if removal of some or all targetBP fails ? 
-									// Go on with the installation of new targetBPs and let clients (i.e. AttributeTranslators) 
-									// handle the errors.
-									@Override
-									protected void handleCompleted() {
-										doBreakpointsAddedInExecutor(oneBPInfo, reinstallContexts, null);
-									}});
-							}
-						}
-						
-						if (updateContexts.size() > 0)
-							modifyTargetBreakpoints(bpinfo.breakpoint, updateContexts, attrDelta);
-	            	}
-	            }
-	        });
-	    } catch (RejectedExecutionException e) {
-			DsfPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e)); //$NON-NLS-1$ //$NON-NLS-2$
-	    }
+		                    	// Process the next pending update for this breakpoint
+		                    	if (fPendingBreakpoints.contains(breakpoint)) {
+		                    		fPendingBreakpoints.remove(breakpoint);
+		                    		new Job("Deferred breakpoint changed job") { //$NON-NLS-1$
+		                                { setSystem(true); }
+		                                @Override
+                                        protected IStatus run(IProgressMonitor monitor) {
+		                                    breakpointChanged(breakpoint, delta);
+		                                    return Status.OK_STATUS;
+		                                };
+		                    		}.schedule();
+		                    	}
+		                    }
+		                };
+		                countingRm.setDoneCount(fPlatformBPs.size());
+
+		                // Mark the breakpoint as being updated and go
+		                fPendingRequests.add(breakpoint);
+		                
+		                // Modify the breakpoint in all the execution contexts
+		                for (final IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
+		                    modifyBreakpoint(dmc, breakpoint, attrsArray, delta, new RequestMonitor(getExecutor(), countingRm));
+		                }
+		            }
+		        });
+		    } catch (CoreException e) {
+                DsfPlugin.getDefault().getLog().log(e.getStatus());
+		    } catch (RejectedExecutionException e) {
+		    }
+		}
 
 	}
 
-	/**
-	 * For the given platform BP, ask the backend to modify all its target BPs
-	 * with the given attribute change. <br>
-	 * This must be called in DSF executor thread.
-	 * 
-	 * @param bp
-	 * @param updateContexts 
-	 * 			  target contexts in which to do the modification.
-	 * @param targetAttrDelta
-	 *            target-recognizable attribute(s) with new values.
-	 */
-	private void modifyTargetBreakpoints(final IBreakpoint bp, Collection<IBreakpointsTargetDMContext> updateContexts, Map<String, Object> targetAttrDelta) {
-		// If the breakpoint is currently being updated, queue the request and exit
-    	if (fRunningEvents.contains(bp)) {
-    		PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.MODIFIED, updateContexts, targetAttrDelta);
-    		updatePendingRequest(bp, pendingEvent);
-			return;
+	public void breakpointRemoved(final IBreakpoint breakpoint, IMarkerDelta delta) {
+
+    	if (fAttributeTranslator.supportsBreakpoint(breakpoint)) {
+            try {
+                getExecutor().execute(new DsfRunnable() {
+                	public void run() {
+                        //TODO pp: need to track pending requests 
+
+                		CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), null) {
+                			@Override
+                			protected void handleError() {
+                				if (getStatus().getSeverity() == IStatus.ERROR) {
+                					DsfPlugin.getDefault().getLog().log(getStatus());
+                				}
+                			}
+                		};
+                		countingRm.setDoneCount(fPlatformBPs.size());
+
+                		// Remove the breakpoint in all the execution contexts
+                		for (IBreakpointsTargetDMContext dmc : fPlatformBPs.keySet()) {
+                			if (fPlatformBPs.get(dmc).remove(breakpoint) != null) {
+                				uninstallBreakpoint(dmc, breakpoint, countingRm);
+                			} else {
+                				// Breakpoint not installed for given context, do nothing.
+                			}
+                		}
+                	}
+                });
+            } catch (RejectedExecutionException e) {
+            }
     	}
 		
-    	CountingRequestMonitor modifyTargetBPCRM = new CountingRequestMonitor(getExecutor(), null) {
-			@Override
-			protected void handleCompleted() {
-				fRunningEvents.remove(bp);
-			}};
-			
-    	int targetBPCount = 0;
-    	
-    	fRunningEvents.add(bp);
-    	
-		for (IBreakpointsTargetDMContext context : updateContexts) {
-			List<TargetBP> targetBPs = fPlatformBPs.get(context).get(bp);
-			if (targetBPs != null) {
-				for (TargetBP tbp : targetBPs) {
-					// this must be an installed breakpoint.
-					assert (tbp.getTargetBreakpoint() != null);
-					
-					targetBPCount++;
-					fBreakpointsService.updateBreakpoint(tbp.getTargetBreakpoint(), targetAttrDelta, modifyTargetBPCRM);
-				}
-			}
-		}
-		
-		modifyTargetBPCRM.setDoneCount(targetBPCount);
 	}
-
-	public void breakpointsRemoved(final IBreakpoint[] bps, IMarkerDelta delta[]) {
-		getExecutor().execute(new DsfRunnable() {
-			public void run() {
-				for (IBreakpoint bp : bps)
-					fBreakpointAttributes.remove(bp);
-			}
-		});
-		
-		doBreakpointsRemoved(bps, null, null);
-	}
-	
-	protected void doBreakpointsRemoved(final IBreakpoint[] bps, final IBreakpointsTargetDMContext bpsTargetDmc, final RequestMonitor rm) {
-	
-		final List<IBreakpoint> bpCandidates = new ArrayList<IBreakpoint>();
-		
-		for (int i = 0; i < bps.length; i++) {
-			IBreakpoint bp = bps[i];
-			
-			if (fAttributeTranslator.supportsBreakpoint(bp)) {
-				bpCandidates.add(bp);
-			}
-		}
-		
-		if (bpCandidates.isEmpty()) { // nothing to do
-			if (rm != null)
-				rm.done();
-			return;
-		}
-		
-		try {
-	        getExecutor().execute(new DsfRunnable() {
-	        	public void run() {
-					Collection<IBreakpointsTargetDMContext> contexts = new ArrayList<IBreakpointsTargetDMContext>();
-					if (bpsTargetDmc == null)
-						contexts.addAll(fPlatformBPs.keySet());
-					else
-						contexts.add(bpsTargetDmc);
-
-					doBreakpointsRemovedInExecutor(bpCandidates.toArray(new IBreakpoint[bpCandidates.size()]), contexts, rm);
-	        	}
-	        });
-        } catch (RejectedExecutionException e) {
-			IStatus status = new Status(IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, 
-					"Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", e);//$NON-NLS-1$ //$NON-NLS-2$
-			if (rm != null) {
-				rm.setStatus(status);
-				rm.done();
-			} else {
-				DsfPlugin.getDefault().getLog().log(status); 
-			}
-        }
-	}
-	
-	protected void doBreakpointsRemovedInExecutor(IBreakpoint[] bpCandidates, 
-			Collection<IBreakpointsTargetDMContext> targetContexts, final RequestMonitor rm) {
-		
-		final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs =  
-			new HashMap<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>>(bpCandidates.length, 1);
-
-		CountingRequestMonitor processPendingCountingRm = new CountingRequestMonitor(getExecutor(), rm) {
-			@Override
-			protected void handleCompleted() {
-				processPendingRequests();
-            	fireUpdateBreakpointsStatus(eventBPs, BreakpointEventType.REMOVED);
-            	if (rm != null)
-            		// don't call this if "rm" is null as this will 
-            		// log errors if any and pack Eclipse error 
-            		// log view with errors useless to user. 
-            		super.handleCompleted();
-			}
-		};
-		int processPendingCountingRmCount = 0;
-		
-		for (final IBreakpoint breakpoint : bpCandidates) {
-
-			// If the breakpoint is currently being updated, queue the request and exit
-        	if (fRunningEvents.contains(breakpoint)) {
-        		PendingEventInfo pendingEvent = new PendingEventInfo(BreakpointEventType.REMOVED, null, targetContexts, processPendingCountingRm);
-                processPendingCountingRmCount++;
-        		updatePendingRequest(breakpoint, pendingEvent);
-				continue;	// handle next breakpoint
-        	}
-
-            processPendingCountingRmCount++;
-
-            final Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]> targetBPs = 
-    			new HashMap<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>(fPlatformBPs.size(), 1);
-    		eventBPs.put(breakpoint, targetBPs);	
-	
-    		CountingRequestMonitor bpTargetsCountingRM = new CountingRequestMonitor(getExecutor(), processPendingCountingRm) {
-				@Override
-				protected void handleCompleted() {
-					// Indicate that the running event has completed
-                	fRunningEvents.remove(breakpoint);
-                	super.handleCompleted();
-				}
-			};
-            
-			int bpTargetsCoutingRMCount = 0;
-
-        	// Mark the breakpoint as being updated and go
-            fRunningEvents.add(breakpoint);
-
-    		// Remove the breakpoint in all the execution contexts
-    		for (final IBreakpointsTargetDMContext dmc : targetContexts) {
-    			
-    			if (fPlatformBPs.get(dmc).containsKey(breakpoint)) {		// there are targetBPs installed 
-    				// now do time-consuming part of the work.
-    				
-    				uninstallBreakpoint(
-    						dmc, breakpoint,
-    						new DataRequestMonitor<List<TargetBP>>(getExecutor(), bpTargetsCountingRM) {
-				    			@Override
-								protected void handleSuccess() {
-				    				targetBPs.put(dmc, getData().toArray(new ITargetBreakpointInfo[getData().size()]));
-				    				super.handleSuccess();
-				    			};
-    						});
-    				bpTargetsCoutingRMCount++;
-    			} else {
-    				// Breakpoint not installed for given context, do nothing.
-    			}
-    		}
-    		
-    		bpTargetsCountingRM.setDoneCount(bpTargetsCoutingRMCount);
-		}
-		
-		processPendingCountingRm.setDoneCount(processPendingCountingRmCount);
-	}
-
-	private void updatePendingRequest(IBreakpoint breakpoint, PendingEventInfo pendingEvent) {
-		LinkedList<PendingEventInfo> pendingEventsList = fPendingEvents.get(breakpoint);
-		if (pendingEventsList == null) {
-			pendingEventsList = new LinkedList<PendingEventInfo>();
-			fPendingEvents.put(breakpoint, pendingEventsList);
-		}
-		if (pendingEventsList.size() > 0 &&
-				pendingEventsList.getLast().fEventType == BreakpointEventType.MODIFIED) {
-			pendingEventsList.removeLast();
-		}
-		pendingEventsList.add(pendingEvent);
-	}
-	
-	private void processPendingRequests() {
-		/*
-		 * This will process only first pending request for each breakpoint,
-		 * whose RequestMonitor (see "processPendingCountingRm" in such methods as 
-		 * doBreakpointsRemovedInExecutor()) will invoke this method again.   
-		 */
-		if (fPendingEvents.isEmpty()) return;  // Nothing to do
-		
-		// Make a copy to avoid ConcurrentModificationException
-		// as we are deleting element in the loop.
-		Set<IBreakpoint> bpsInPendingEvents = new HashSet<IBreakpoint>(fPendingEvents.keySet()); 
-		for (IBreakpoint bp : bpsInPendingEvents) {
-	    	if (! fRunningEvents.contains(bp)) {
-				LinkedList<PendingEventInfo> eventInfoList = fPendingEvents.get(bp);
-
-		    	// Process the first pending request for this breakpoint
-		   		PendingEventInfo eventInfo = eventInfoList.removeFirst();
-	
-				if (eventInfoList.isEmpty())
-					fPendingEvents.remove(bp);
-	
-				switch (eventInfo.fEventType) {
-				case ADDED:
-					doBreakpointsAddedInExecutor(new PlatformBreakpointInfo[] {eventInfo.fBPInfo}, eventInfo.fBPTargetContexts, eventInfo.fRequestMonitor);
-					break;
-				case MODIFIED:
-					modifyTargetBreakpoints(bp, eventInfo.fBPTargetContexts, eventInfo.fAttributeDelta);
-					break;
-				case REMOVED:
-					doBreakpointsRemovedInExecutor(new IBreakpoint[]{bp}, eventInfo.fBPTargetContexts, eventInfo.fRequestMonitor);
-					break;
-				}
-	    	}
-		}
-	}
-	
-	private void fireUpdateBreakpointsStatus(final Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> eventBPs, final BreakpointEventType eventType) {
-        // Update breakpoint status
-        new Job("Breakpoint status update") { //$NON-NLS-1$
-            { setSystem(true); }
-            @Override
-            protected IStatus run(IProgressMonitor monitor) {
-            	for (IBreakpoint bp : eventBPs.keySet()) {
-            		fAttributeTranslator.updateBreakpointStatus(bp);
-            	}
-                
-                if (fAttributeTranslator2 != null) {
-                	fAttributeTranslator2.updateBreakpointsStatus(eventBPs, eventType);
-                }
-                else
-                	for (IBreakpoint bp : eventBPs.keySet()) {
-                		fAttributeTranslator.updateBreakpointStatus(bp);
-                	}
-                	
-
-                return Status.OK_STATUS;
-            };
-        }.schedule();
-		
-	}
-
-    /**
-     * Determine the set of modified attributes.
-     * 
-     * @param oldAttributes old map of attributes.
-     * @param newAttributes new map of attributes.
-     * @return new and changed attribute in the new map. May be empty indicating the two maps are equal.
-     */
-    private Map<String, Object> getAttributesDelta(Map<String, Object> oldAttributes, Map<String, Object> newAttributes) {
-
-        Map<String, Object> delta = new HashMap<String,Object>();
-
-        Set<String> oldKeySet = oldAttributes.keySet();
-        Set<String> newKeySet = newAttributes.keySet();
-
-        Set<String> commonKeys  = new HashSet<String>(newKeySet); commonKeys.retainAll(oldKeySet);
-        Set<String> addedKeys   = new HashSet<String>(newKeySet); addedKeys.removeAll(oldKeySet);
-        Set<String> removedKeys = new HashSet<String>(oldKeySet); removedKeys.removeAll(newKeySet);
-
-        // Add the modified attributes
-        for (String key : commonKeys) {
-            if (!(oldAttributes.get(key).equals(newAttributes.get(key))))
-                delta.put(key, newAttributes.get(key));
-        }
-
-        // Add the new attributes
-        for (String key : addedKeys) {
-            delta.put(key, newAttributes.get(key));
-        }
-
-        // Remove the deleted attributes
-        for (String key : removedKeys) {
-            delta.put(key, null);
-        }
-
-        return delta;
-    }
 }
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslatorExtension.java	Fri Dec 04 14:31:59 2009 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*******************************************************************************
- * 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:
- *     Wind River Systems - initial API and implementation
- *     Nokia - enhanced to work for both GDB and EDC.  Nov. 2009.
- *******************************************************************************/
-package org.eclipse.cdt.dsf.debug.service;
-
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
-import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator.BreakpointEventType;
-import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator.ITargetBreakpointInfo;
-import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.debug.core.model.IBreakpoint;
-
-/**
- * Enhanced breakpoint attribute translator interface
- * 
- * @since 2.1
- */
-
-public interface IBreakpointAttributeTranslatorExtension extends IBreakpointAttributeTranslator {
-	/**
-	 * Resolve the breakpoint in given context. A platform BP may be mapped to
-	 * two or more target BPs, e.g. a breakpoint in an in-line function may be
-	 * mapped to several target BPs, or a thread-specific BP may be mapped to
-	 * several target BPs each of which is for one thread. This method will get
-	 * the list of attribute maps each of which corresponds to one target BP.<br>
-	 * <br>
-	 * This method is and must be called in DSF execution thread.
-	 * 
-	 * @param context
-	 *            - a IBreakpointsTargetDMContext object (which could be a
-	 *            process or a loaded module) in which we locate target BPs for
-	 *            the platform BP. Cannot be null.
-	 * @param breakpoint
-	 *            - platform breakpoint.
-	 * @param bpAttributes
-	 *            - all attributes of the breakpoint, usually output from
-	 *            {@link #getAllBreakpointAttributes(IBreakpoint, boolean)}.
-	 * @param drm
-	 *            - on completion of the request, the DataRequestMonitor
-	 *            contains one or more attribute maps each of which
-	 *            corresponding to one target breakpoint.
-	 * @throws CoreException
-	 */
-    public void resolveBreakpoint(IBreakpointsTargetDMContext context, IBreakpoint breakpoint, 
-    		Map<String, Object> bpAttributes, DataRequestMonitor<List<Map<String, Object>>> drm);
-
-	/**
-	 * Get all platform defined attributes for a breakpoint plus all attributes
-	 * defined by any breakpoint extension such as ICBreakpointExtension in CDT.
-	 * In other words, get all attributes available from UI. <br>
-	 * <br>
-	 * The attributes returned are independent of runtime context (process,
-	 * module, etc), whereas attributes from
-	 * {@link #resolveBreakpoint(IBreakpointsTargetDMContext, IBreakpoint, Map, DataRequestMonitor)}
-	 * are context sensitive. <br>
-	 * <br>
-	 * Note this method must not be called in DSF dispatch thread because we are
-	 * accessing the resources system to retrieve the breakpoint attributes.
-	 * Accessing the resources system potentially requires using global locks.
-	 * 
-	 * @param platformBP
-	 * @param bpManagerEnabled
-	 * @return list of target (debugger implementation) recognizable attributes.
-	 * @throws CoreException
-	 */
-    public Map<String, Object> getAllBreakpointAttributes(IBreakpoint platformBP, boolean bpManagerEnabled) throws CoreException;
-
-	/**
-	 * Convert platform breakpoint attributes to target attributes. This usually
-	 * involves changing attributes keys to target recognizable ones. For
-	 * instance, GDB integration has its own breakpoint attribute keys. <br>
-	 * 
-	 * @param platformBPAttr
-	 * @return
-	 */
-    public Map<String, Object> convertAttributes(Map<String, Object> platformBPAttr);
-        
-    /**
-     * Update platform about breakpoint status change, e.g. breakpoint installed on target successfully or breakpoint
-     * removed from target successfully.<br>
-     * <br>
-     * Note this method is not and must not be called in DSF dispatch thread.
-     * 
-     * @param bpsInfo
-     * @param eventType
-     */
-    public void updateBreakpointsStatus(Map<IBreakpoint, Map<IBreakpointsTargetDMContext, ITargetBreakpointInfo[]>> bpsInfo, BreakpointEventType eventType);
-
-	/**
-	 * This is enhanced version of
-	 * {@link #canUpdateAttributes(org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext, Map)}
-	 * in that this API gives more context parameters so that client can make
-	 * decision on a finer granularity when needed.<br>
-	 * <br>
-	 * This will be called in DSF dispatch thread.
-	 * 
-	 * @param bp  platform breakpoint.
-	 * @param context 
-	 * @param attributes target-recognizable attributes.
-	 * @return false as long as one of the attributes cannot be updated by client, otherwise true.
-	 */
-	public boolean canUpdateAttributes(IBreakpoint bp, IBreakpointsTargetDMContext context, Map<String, Object> attributes);
-}
\ No newline at end of file
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/launch/PDAServicesInitSequence.java	Fri Dec 04 14:31:59 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/launch/PDAServicesInitSequence.java	Fri Dec 04 14:32:55 2009 -0600
@@ -75,7 +75,7 @@
                 // Create the breakpoint mediator and start tracking PDA breakpoints.
 
                 final BreakpointsMediator bpmService = new BreakpointsMediator(
-                    fSession, new PDABreakpointAttributeTranslator(fCommandControl.getContext()));
+                    fSession, new PDABreakpointAttributeTranslator());
                 bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
                     @Override
                     protected void handleSuccess() {
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDABreakpointAttributeTranslator.java	Fri Dec 04 14:31:59 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDABreakpointAttributeTranslator.java	Fri Dec 04 14:32:55 2009 -0600
@@ -14,15 +14,10 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 
 import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator;
 import org.eclipse.cdt.dsf.debug.service.IBreakpointAttributeTranslator;
-import org.eclipse.cdt.dsf.debug.service.BreakpointsMediator.ITargetBreakpointInfo;
 import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
-import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
 import org.eclipse.cdt.examples.dsf.pda.PDAPlugin;
 import org.eclipse.cdt.examples.dsf.pda.breakpoints.PDALineBreakpoint;
 import org.eclipse.cdt.examples.dsf.pda.breakpoints.PDAWatchpoint;
@@ -59,18 +54,9 @@
         PDAWatchpoint.MODIFICATION
     };
 
-    private final IBreakpointsTargetDMContext fBreakpointsTargetDmc;
-    
-	private BreakpointsMediator fMediator;
-	
-	public PDABreakpointAttributeTranslator(IBreakpointsTargetDMContext breakpointsTargetDmc) {
-		fBreakpointsTargetDmc = breakpointsTargetDmc;
-	}
-	
     // PDA breakpoints translator doesn't keep any state and it doesn't 
     // need to initialize or clean up.
     public void initialize(BreakpointsMediator mediator) {
-    	fMediator = mediator;
     }
 
     public void dispose() {
@@ -142,38 +128,8 @@
         return bp.getModelIdentifier().equals(PDAPlugin.ID_PDA_DEBUG_MODEL);
     }
 
-    public void updateBreakpointStatus(final IBreakpoint bp) {
-    	Future<ITargetBreakpointInfo[]> future = fMediator.getSession().getExecutor().submit(new Callable<ITargetBreakpointInfo[]>() {
-    		public ITargetBreakpointInfo[] call() throws Exception {
-				return fMediator.getTargetBreakpoints(fBreakpointsTargetDmc, bp);
-    		}
-    	});
-    	
-    	
-    	ITargetBreakpointInfo[] targetBPs = null;
-		try {
-			targetBPs = future.get();
-		} catch (InterruptedException e1) {
-		} catch (ExecutionException e1) {
-			assert false;
-		}
-		
-    	try {
-    		boolean oldInstalled = ((PDALineBreakpoint)bp).getInstalled();
-    		boolean newInstalled = false;
-    		for (int i = 0; targetBPs != null && i < targetBPs.length; i++) {
-    			if (targetBPs[i].getTargetBreakpoint() != null) {
-    				newInstalled = true;
-    				break;
-    			}
-    		}
-    		if (oldInstalled != newInstalled) {
-    			((PDALineBreakpoint)bp).setInstalled(newInstalled);
-    		}
-    		System.out.println(bp.toString() + " installed = " + newInstalled);
-    	} catch (CoreException e) {
-    		// Marker access race condition: most likely the breakpoint has already been removed
-    	}
+    public void updateBreakpointStatus(IBreakpoint bp) {
+        // PDA breakpoints do not support status reporting
     }
 
 }