backed out all changes related to BreakpointsMediator and moved the new mediator into EDC to be an EDC-specific service. Two problems solved here:
authorl12wang
Wed, 02 Dec 2009 18:27:49 -0600
changeset 122 d94b9ba55bed
parent 121 d2bbceb7cdeb
child 124 e120fb809ed2
backed out all changes related to BreakpointsMediator and moved the new mediator into EDC to be an EDC-specific service. Two problems solved here: 1. It will take some time for Pawel (and other DSF/GDB committers) to review and accept the big change to the mediator, namely the new mediator won't get into CDT repository for who knows how long. That would make EDC debugger in CDT repository a handicapped debugger (breakpoints not shown as resolved, disabled breakpoint still stops program, breakpoints in inline-function do not work well, etc). 2. All mediator related change is kept in our local CDT repository, which makes Ken's life harder when he tries to sync it with upstream.
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.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java
cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java
cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java
cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IBreakpointAttributeTranslatorExtension.java
cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/launch/PDAServicesInitSequence.java
cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDABreakpointAttributeTranslator.java
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointAttributeTranslator.java	Wed Dec 02 09:47:49 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	Wed Dec 02 09:47:49 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java	Wed Dec 02 18:27:49 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	Wed Dec 02 09:47:49 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java	Wed Dec 02 18:27:49 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	Wed Dec 02 09:47:49 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/BreakpointsMediator.java	Wed Dec 02 18:27:49 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	Wed Dec 02 09:47:49 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	Wed Dec 02 09:47:49 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/launch/PDAServicesInitSequence.java	Wed Dec 02 18:27:49 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	Wed Dec 02 09:47:49 2009 -0600
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDABreakpointAttributeTranslator.java	Wed Dec 02 18:27:49 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
     }
 
 }