/*******************************************************************************
 *  Copyright (c) 2000, 2016 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.core;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugException;
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.eclipse.debug.core.model.IBreakpointImportParticipant;

import com.ibm.icu.text.MessageFormat;

/**
 * The breakpoint manager manages all registered breakpoints for the Debug plug-in. It is
 * instantiated by the Debug plug-in at startup.
 * <p>
 * <strong>Note:</strong> This manager is created while the Debug plug-in is started, but it
 * will not automatically be initialized. Client code that expects markers and breakpoints to be
 * initialized must call {@link #ensureInitialized()}.
 * </p>
 *
 * @see IBreakpointManager
 */
public class BreakpointManager implements IBreakpointManager, IResourceChangeListener {

	/**
	 * Constants for breakpoint add/remove/change updates
	 */
	private final static int ADDED = 0;
	private final static int REMOVED = 1;
	private final static int CHANGED = 2;

	/**
	 * A collection of breakpoints registered with this manager.
	 */
	private Vector<IBreakpoint> fBreakpoints = null;

	/**
	 * Map of breakpoint import participants.
	 * Map has the form:
	 * <pre>Map(String - marker_id, List of {@link IBreakpointImportParticipant})</pre>
	 */
	private HashMap<String, ArrayList<BreakpointImportParticipantDelegate>> fImportParticipants = null;

	/**
	 * A system default import participant that performs legacy comparison support
	 * when no participants are provided for a given type.
	 *
	 * @since 3.5
	 */
	private IBreakpointImportParticipant fDefaultParticipant = null;

	/**
	 * A collection of breakpoint markers that have received a POST_CHANGE notification
	 * that they have changed before a POST_BUILD notification of add. This allows us
	 * to tell if a marker has been created & changed since the breakpoint has been
	 * registered (see bug 138473).
	 */
	private Set<IMarker> fPostChangMarkersChanged = new HashSet<IMarker>();

	/**
	 * A collection of breakpoint markers that have received a POST_BUILD notification
	 * of being added.
	 */
	private Set<IMarker> fPostBuildMarkersAdded = new HashSet<IMarker>();

	/**
	 * Collection of breakpoints being added currently. Used to
	 * suppress change notification of "REGISTERED" attribute when
	 * being added.
	 */
	private List<IBreakpoint> fSuppressChange = new ArrayList<IBreakpoint>();

	/**
	 * A table of breakpoint extension points, keyed by
	 * marker type
	 * key: a marker type
	 * value: the breakpoint extension which corresponds to that marker type
	 */
	private HashMap<String, IConfigurationElement> fBreakpointExtensions;

	/**
	 * Collection of markers that associates markers to breakpoints
	 * key: a marker
	 * value: the breakpoint which contains that marker
	 */
	private HashMap<IMarker, IBreakpoint> fMarkersToBreakpoints;

	/**
	 * Collection of breakpoint listeners.
	 */
	private ListenerList<IBreakpointListener> fBreakpointListeners= new ListenerList<>();

	/**
	 * Collection of (plural) breakpoint listeners.
	 */
	private ListenerList<IBreakpointsListener> fBreakpointsListeners= new ListenerList<>();

	/**
	 * Singleton resource delta visitor which handles marker
	 * additions, changes, and removals.
	 */
	private static BreakpointManagerVisitor fgVisitor;

	/**
	 * Collection of breakpoint manager listeners which are
	 * notified when this manager's state changes.
	 */
	private ListenerList<IBreakpointManagerListener> fBreakpointManagerListeners= new ListenerList<>();

	/**
	 * Breakpoint which acts a the triggering point in a workspace.
	 */
	private Set<IBreakpoint> fTriggerPointBreakpointList = new LinkedHashSet<>();


	/**
	 * Listens to POST_CHANGE notifications of breakpoint markers to detect when
	 * a breakpoint is added & changed before the POST_BUILD add notification is
	 * sent.
	 */
	class PostChangeListener implements IResourceChangeListener {

		private PostChangeVisitor fVisitor = new PostChangeVisitor();

		/* (non-Javadoc)
		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
		 */
		@Override
		public void resourceChanged(IResourceChangeEvent event) {
			IResourceDelta delta= event.getDelta();
			if (delta != null) {
				try {
					delta.accept(fVisitor);
				} catch (CoreException ce) {
					DebugPlugin.log(ce);
				}
			}
		}

	}

	/**
	 * Default implementation of a breakpoint import participant
	 *
	 * @since 3.5
	 */
	class DefaultImportParticipant implements IBreakpointImportParticipant {

		@Override
		public boolean matches(Map<String, Object> attributes, IBreakpoint breakpoint) throws CoreException {
			//perform legacy comparison
			IMarker marker = breakpoint.getMarker();
			String type = (String) attributes.get("type"); //$NON-NLS-1$
			Integer line = (Integer) attributes.get(IMarker.LINE_NUMBER);
			Object localline = marker.getAttribute(IMarker.LINE_NUMBER);
			String localtype = marker.getType();
			if (type.equals(localtype)) {
				if(line != null && line.equals(localline)) {
					return true;
				}
				else if(line == null) {
					return true;
				}
			}
			return false;
		}
		@Override
		public void verify(IBreakpoint breakpoint) throws CoreException {}
	}

	/**
	 * The listener
	 */
	private PostChangeListener fPostChangeListener = new PostChangeListener();

	class PostChangeVisitor implements IResourceDeltaVisitor {

		/* (non-Javadoc)
		 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
		 */
		@Override
		public boolean visit(IResourceDelta delta) throws CoreException {
			if (delta == null) {
				return false;
			}
			IMarkerDelta[] markerDeltas= delta.getMarkerDeltas();
			for (int i= 0; i < markerDeltas.length; i++) {
				IMarkerDelta markerDelta= markerDeltas[i];
				if (markerDelta.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
					switch (markerDelta.getKind()) {
						case IResourceDelta.ADDED :
							break;
						case IResourceDelta.REMOVED :
							break;
						case IResourceDelta.CHANGED :
							IMarker marker = markerDelta.getMarker();
							synchronized (fPostChangMarkersChanged) {
								if (!fPostBuildMarkersAdded.contains(marker)) {
									fPostChangMarkersChanged.add(marker);
								}
							}
							break;
						default:
							break;
					}
				}
			}
			return true;
		}

	}

	/**
	 * Constructs a new breakpoint manager.
	 */
	public BreakpointManager() {
		fMarkersToBreakpoints = new HashMap<IMarker, IBreakpoint>(10);
		fBreakpointExtensions = new HashMap<String, IConfigurationElement>(15);
	}

	/**
	 * Loads all the breakpoints on the given resource.
	 *
	 * @param resource the resource which contains the breakpoints
	 * @param notify whether to notify of the breakpoint additions
	 * @throws CoreException if a problem is encountered
	 */
	private void loadBreakpoints(IResource resource, boolean notify) throws CoreException {
		initBreakpointExtensions();
		IMarker[] markers= getPersistedMarkers(resource);
		List<IBreakpoint> added = new ArrayList<IBreakpoint>();
		for (int i = 0; i < markers.length; i++) {
			IMarker marker= markers[i];
			try {
				IBreakpoint breakpoint = createBreakpoint(marker);
				synchronized (fPostChangMarkersChanged) {
					fPostBuildMarkersAdded.add(marker);
				}
				if (breakpoint.isRegistered()) {
					added.add(breakpoint);

				}
				if (breakpoint.isTriggerPoint()) {
					addTriggerBreakpoint(breakpoint);
				}
			} catch (DebugException e) {
				DebugPlugin.log(e);
			}
		}
		addBreakpoints(added.toArray(new IBreakpoint[added.size()]), notify);
	}

	/**
	 * Returns the persisted markers associated with the given resource.
	 *
	 * Delete any invalid breakpoint markers. This is done at startup rather
	 * than shutdown, since the changes made at shutdown are not persisted as
	 * the workspace state has already been saved. See bug 7683.
	 *
	 * Since the <code>TRANSIENT</code> marker attribute/feature has been added,
	 * we no longer have to manually delete non-persisted markers - the platform
	 * does this for us (at shutdown, transient markers are not saved). However,
	 * the code is still present to delete non-persisted markers from old
	 * workspaces.
	 * @param resource the {@link IResource} to get markers for
	 * @return the complete listing of persisted markers for the given {@link IResource}
	 * @throws CoreException if a problem is encountered
	 */
	protected IMarker[] getPersistedMarkers(IResource resource) throws CoreException {
		IMarker[] markers= resource.findMarkers(IBreakpoint.BREAKPOINT_MARKER, true, IResource.DEPTH_INFINITE);
		final List<IMarker> delete = new ArrayList<IMarker>();
		List<IMarker> persisted = new ArrayList<IMarker>();
		for (int i = 0; i < markers.length; i++) {
			IMarker marker= markers[i];
			// ensure the marker has a valid model identifier attribute
			// and delete the breakpoint if not
			String modelId = marker.getAttribute(IBreakpoint.ID, null);
			if (modelId == null) {
				// marker with old/invalid format - delete
				delete.add(marker);
			} else if (!marker.getAttribute(IBreakpoint.PERSISTED, true)) {
				// the breakpoint is marked as not to be persisted,
				// schedule for deletion
				delete.add(marker);
			} else {
				persisted.add(marker);
			}
		}
		// delete any markers that are not to be restored
		if (!delete.isEmpty()) {
            final IMarker[] delMarkers = delete.toArray(new IMarker[delete.size()]);
			IWorkspaceRunnable wr = new IWorkspaceRunnable() {
				@Override
				public void run(IProgressMonitor pm) throws CoreException {
                    for (int i = 0; i < delMarkers.length; i++) {
                        IMarker marker = delMarkers[i];
                        marker.delete();
                    }
				}
			};
			new BreakpointManagerJob(wr).schedule();
		}
		return persisted.toArray(new IMarker[persisted.size()]);
	}

	/**
	 * Removes this manager as a resource change listener
	 * and removes all breakpoint listeners.
	 */
	public void shutdown() {
		getWorkspace().removeResourceChangeListener(this);
		getWorkspace().removeResourceChangeListener(fPostChangeListener);
		fBreakpointListeners.clear();
        fBreakpointsListeners.clear();
        fBreakpointManagerListeners.clear();
        if(fImportParticipants != null) {
        	fImportParticipants.clear();
        	fImportParticipants = null;
        	fDefaultParticipant = null;
        }
        if(fBreakpoints != null) {
        	fBreakpoints.clear();
        	fBreakpoints = null;
        }
        if(fMarkersToBreakpoints != null) {
        	fMarkersToBreakpoints.clear();
        }
	}

	/**
	 * Find the defined breakpoint extensions and cache them for use in recreating
	 * breakpoints from markers.
	 */
	private void initBreakpointExtensions() {
		IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_BREAKPOINTS);
		IConfigurationElement[] elements = ep.getConfigurationElements();
		for (int i= 0; i < elements.length; i++) {
			String markerType = elements[i].getAttribute(IConfigurationElementConstants.MARKER_TYPE);
			String className = elements[i].getAttribute(IConfigurationElementConstants.CLASS);
			if (markerType == null) {
				DebugPlugin.log(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "Breakpoint extension " + elements[i].getDeclaringExtension().getUniqueIdentifier() + " missing required attribute: markerType", null)); //$NON-NLS-1$ //$NON-NLS-2$
			} else if (className == null){
				DebugPlugin.log(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "Breakpoint extension " + elements[i].getDeclaringExtension().getUniqueIdentifier() + " missing required attribute: class", null)); //$NON-NLS-1$ //$NON-NLS-2$
			} else {
				fBreakpointExtensions.put(markerType, elements[i]);
			}
		}
	}

	/**
	 * Convenience method to get the workspace
	 * @return the default {@link IWorkspace}
	 */
	private IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}

	/**
	 * @see IBreakpointManager#getBreakpoint(IMarker)
	 */
	@Override
	public IBreakpoint getBreakpoint(IMarker marker) {
		// ensure that breakpoints are initialized
		getBreakpoints0();
		return fMarkersToBreakpoints.get(marker);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#getBreakpoints()
	 */
	@Override
	public IBreakpoint[] getBreakpoints() {
		IBreakpoint[] temp = new IBreakpoint[0];
		Vector<IBreakpoint> breakpoints = getBreakpoints0();
		synchronized (breakpoints) {
			temp = new IBreakpoint[breakpoints.size()];
			breakpoints.copyInto(temp);
		}
		return temp;
	}

	/**
	 * Ensures that this manager is initialized.
	 * <p>
	 * This manager is created while the Debug plug-in is started, but it will not automatically
	 * be initialized. Client code that expects markers and breakpoints to be initialized must call
	 * this method.
	 * </p>
	 *
	 * @since 3.8
	 */
	public void ensureInitialized() {
		getBreakpoints0();
	}

	/**
	 * The BreakpointManager waits to load the breakpoints
	 * of the workspace until a request is made to retrieve the
	 * breakpoints.
	 * @return the underlying {@link Vector} of breakpoints
	 */
	private synchronized Vector<IBreakpoint> getBreakpoints0() {
		if (fBreakpoints == null) {
			initializeBreakpoints();
		}
		return fBreakpoints;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#getBreakpoints(java.lang.String)
	 */
	@Override
	public IBreakpoint[] getBreakpoints(String modelIdentifier) {
		Vector<IBreakpoint> allBreakpoints = getBreakpoints0();
		synchronized (allBreakpoints) {
			ArrayList<IBreakpoint> temp = new ArrayList<IBreakpoint>(allBreakpoints.size());
			for (IBreakpoint breakpoint : allBreakpoints) {
				String id= breakpoint.getModelIdentifier();
				if (id != null && id.equals(modelIdentifier)) {
					temp.add(breakpoint);
				}
			}
			return temp.toArray(new IBreakpoint[temp.size()]);
		}
	}

	/**
	 * Loads the list of breakpoints from the breakpoint markers in the
	 * workspace. Start listening to resource deltas.
	 */
	private void initializeBreakpoints() {
		setBreakpoints(new Vector<IBreakpoint>(10));
		try {
			loadBreakpoints(getWorkspace().getRoot(), false);
			getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD);
			getWorkspace().addResourceChangeListener(fPostChangeListener, IResourceChangeEvent.POST_CHANGE);
		} catch (CoreException ce) {
			DebugPlugin.log(ce);
			setBreakpoints(new Vector<IBreakpoint>(0));
		}
	}

	/**
	 * @see IBreakpointManager#isRegistered(IBreakpoint)
	 */
	@Override
	public boolean isRegistered(IBreakpoint breakpoint) {
		return getBreakpoints0().contains(breakpoint);
	}


	/**
	 * @see IBreakpointManager#removeBreakpoint(IBreakpoint, boolean)
	 */
	@Override
	public void removeBreakpoint(IBreakpoint breakpoint, boolean delete) throws CoreException {
		removeBreakpoints(new IBreakpoint[]{breakpoint}, delete);
	}

	/**
	 * @see IBreakpointManager#removeBreakpoints(IBreakpoint[], boolean)
	 */
	@Override
	public void removeBreakpoints(IBreakpoint[] breakpoints, final boolean delete) throws CoreException {
		final List<IBreakpoint> remove = new ArrayList<IBreakpoint>(breakpoints.length);
		List<IBreakpoint> bps = getBreakpoints0();
		for (int i = 0; i < breakpoints.length; i++) {
			IBreakpoint breakpoint = breakpoints[i];
			if (bps.contains(breakpoint)) {
				remove.add(breakpoint);
			}
		}
		if (!remove.isEmpty()) {
			for (IBreakpoint breakpoint : remove) {
				bps.remove(breakpoint);
				fMarkersToBreakpoints.remove(breakpoint.getMarker());
			}
			fireUpdate(remove, null, REMOVED);
			refreshTriggerpointDisplay();
			IWorkspaceRunnable r = new IWorkspaceRunnable() {
				@Override
				public void run(IProgressMonitor montitor) throws CoreException {
					for (IBreakpoint breakpoint : remove) {
						if (delete) {
							breakpoint.delete();
						} else {
							// if the breakpoint is being removed from the manager
							// because the project is closing, the breakpoint should
							// remain as registered, otherwise, the breakpoint should
							// be marked as unregistered
							IMarker marker = breakpoint.getMarker();
							if (marker.exists()) {
								IProject project = breakpoint.getMarker().getResource().getProject();
								if (project == null || project.isOpen()) {
									breakpoint.setRegistered(false);
								}
							}
						}
					}
				}
			};
			getWorkspace().run(r, null, 0, null);
		}
	}

	/**
	 * Create a breakpoint for the given marker. The created breakpoint
	 * is of the type specified in the breakpoint extension associated
	 * with the given marker type.
	 *
	 * @param marker marker to create a breakpoint for
	 * @return a breakpoint on this marker
	 * @exception DebugException if breakpoint creation fails. Reasons for
	 *  failure include:
	 * <ol>
	 * <li>The breakpoint manager cannot determine what kind of breakpoint
	 *     to instantiate for the given marker type</li>
	 * <li>A lower level exception occurred while accessing the given marker</li>
	 * </ol>
	 */
	public IBreakpoint createBreakpoint(IMarker marker) throws DebugException {
		IBreakpoint breakpoint= fMarkersToBreakpoints.get(marker);
		if (breakpoint != null) {
			return breakpoint;
		}
		try {
			IConfigurationElement config = fBreakpointExtensions.get(marker.getType());
			if (config == null) {
				throw new DebugException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
 DebugException.CONFIGURATION_INVALID, MessageFormat.format(DebugCoreMessages.BreakpointManager_Missing_breakpoint_definition, new Object[] { marker.getType() }), null));
			}
			Object object = config.createExecutableExtension(IConfigurationElementConstants.CLASS);
			if (object instanceof IBreakpoint) {
				breakpoint = (IBreakpoint)object;
				breakpoint.setMarker(marker);
			} else {
				DebugPlugin.log(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "Breakpoint extension " + config.getDeclaringExtension().getUniqueIdentifier() + " missing required attribute: class", null)); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return breakpoint;
		} catch (CoreException e) {
			throw new DebugException(e.getStatus());
		}
	}

	/**
	 * @see IBreakpointManager#addBreakpoint(IBreakpoint)
	 */
	@Override
	public void addBreakpoint(IBreakpoint breakpoint) throws CoreException {
		addBreakpoints(new IBreakpoint[]{breakpoint});
	}

	/**
	 * @see IBreakpointManager#addBreakpoints(IBreakpoint[])
	 */
	@Override
	public void addBreakpoints(IBreakpoint[] breakpoints) throws CoreException {
	    addBreakpoints(breakpoints, true);
	}

	/**
	 * Registers the given breakpoints and notifies listeners if specified.
	 *
	 * @param breakpoints the breakpoints to register
	 * @param notify whether to notify listeners of the add
	 * @throws CoreException if a problem is encountered
	 */
	private void addBreakpoints(IBreakpoint[] breakpoints, boolean notify) throws CoreException {
		List<IBreakpoint> added = new ArrayList<IBreakpoint>(breakpoints.length);
		final List<IBreakpoint> update = new ArrayList<IBreakpoint>();
		for (int i = 0; i < breakpoints.length; i++) {
			IBreakpoint breakpoint = breakpoints[i];
			if (!getBreakpoints0().contains(breakpoint)) {
				verifyBreakpoint(breakpoint);
				if (breakpoint.isRegistered()) {
				    // If notify == false, the breakpoints are just being added at startup
					added.add(breakpoint);
					getBreakpoints0().add(breakpoint);
					fMarkersToBreakpoints.put(breakpoint.getMarker(), breakpoint);
				} else {
					// need to update the 'registered' and/or 'group' attributes
					update.add(breakpoint);
				}
			}
		}
		if (notify) {
		    fireUpdate(added, null, ADDED);
		}
		if (!update.isEmpty()) {
			IWorkspaceRunnable r = new IWorkspaceRunnable() {
				@Override
				public void run(IProgressMonitor monitor) throws CoreException {
					List<IBreakpoint> bps = getBreakpoints0();
					for (IBreakpoint breakpoint : update) {
						bps.add(breakpoint);
						breakpoint.setRegistered(true);
						fMarkersToBreakpoints.put(breakpoint.getMarker(), breakpoint);
					}
				}
			};
			// Need to suppress change notification, since this is really
			// an add notification
			fSuppressChange.addAll(update);
			getWorkspace().run(r, null, 0, null);
			fSuppressChange.removeAll(update);
			if (notify) {
			    fireUpdate(update, null, ADDED);
			}
		}
	}

	/**
	 * Returns whether change notification is to be suppressed for the given breakpoint.
	 * Used when adding breakpoints and changing the "REGISTERED" attribute.
	 *
	 * @param breakpoint the breakpoint
	 * @return boolean whether change notification is suppressed
	 */
	protected boolean isChangeSuppressed(IBreakpoint breakpoint) {
		return fSuppressChange.contains(breakpoint);
	}

	/**
	 * @see IBreakpointManager#fireBreakpointChanged(IBreakpoint)
	 */
	@Override
	public void fireBreakpointChanged(IBreakpoint breakpoint) {
		if (getBreakpoints0().contains(breakpoint)) {
			List<IBreakpoint> changed = new ArrayList<IBreakpoint>();
			changed.add(breakpoint);
			fireUpdate(changed, null, CHANGED);
		}
	}

	/**
	 * Verifies that the breakpoint marker has the minimal required attributes,
	 * and throws a debug exception if not.
	 * @param breakpoint the {@link IBreakpoint} to verify
	 * @throws DebugException if a problem is encountered
	 */
	private void verifyBreakpoint(IBreakpoint breakpoint) throws DebugException {
		try {
			String id= breakpoint.getModelIdentifier();
			if (id == null) {
				throw new DebugException(new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(),
					DebugException.CONFIGURATION_INVALID, DebugCoreMessages.BreakpointManager_Missing_model_identifier, null));
			}
		} catch (CoreException e) {
			throw new DebugException(e.getStatus());
		}
	}

	/**
	 * A resource has changed. Traverses the delta for breakpoint changes.
	 *
	 * @param event resource change event
	 */
	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		IResourceDelta delta= event.getDelta();
		if (delta != null) {
			try {
				if (fgVisitor == null) {
					fgVisitor= new BreakpointManagerVisitor();
				}
				delta.accept(fgVisitor);
				fgVisitor.update();
			} catch (CoreException ce) {
				DebugPlugin.log(ce);
			}
		}
	}

	/**
	 * Visitor for handling resource deltas
	 */
	class BreakpointManagerVisitor implements IResourceDeltaVisitor {
		/**
		 * Moved markers
		 */
		private List<IMarker> fMoved = new ArrayList<IMarker>();
		/**
		 * Removed breakpoints
		 */
		private List<IBreakpoint> fRemoved = new ArrayList<IBreakpoint>();

		/**
		 * Added breakpoints.
		 * @since 3.7
		 */
		private List<IBreakpoint> fAdded = new ArrayList<IBreakpoint>();

		/**
		 * Changed breakpoints and associated marker deltas
		 */
		private List<IBreakpoint> fChanged = new ArrayList<IBreakpoint>();
		private List<IMarkerDelta> fChangedDeltas = new ArrayList<IMarkerDelta>();

		/**
		 * Resets the visitor for a delta traversal - empties
		 * collections of removed/changed breakpoints.
		 */
		protected void reset() {
			fMoved.clear();
			fRemoved.clear();
			fAdded.clear();
			fChanged.clear();
			fChangedDeltas.clear();
		}

		/**
		 * Performs updates on accumulated changes, and fires change notification after
		 * a traversal. Accumulated updates are reset.
		 */
		public void update() {
			if (!fMoved.isEmpty()) {
				// delete moved markers
				IWorkspaceRunnable wRunnable= new IWorkspaceRunnable() {
					@Override
					public void run(IProgressMonitor monitor) throws CoreException {
                        IMarker[] markers = fMoved.toArray(new IMarker[fMoved.size()]);
						for (int i = 0; i < markers.length; i++) {
                            markers[i].delete();
                        }
					}
				};
				try {
					getWorkspace().run(wRunnable, null, 0, null);
				} catch (CoreException e) {
				}
			}
			if (!fRemoved.isEmpty()) {
				try {
					removeBreakpoints(fRemoved.toArray(new IBreakpoint[fRemoved.size()]), false);
				} catch (CoreException e) {
					DebugPlugin.log(e);
				}
			}
			if (!fAdded.isEmpty()) {
				try {
					IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
						@Override
						public void run(IProgressMonitor monitor) throws CoreException {
							for (IBreakpoint breakpoint : fAdded) {
								breakpoint.getMarker().setAttribute(DebugPlugin.ATTR_BREAKPOINT_IS_DELETED, false);
								breakpoint.setRegistered(true);
							}
						}
					};
					getWorkspace().run(runnable, null, 0, null);
					addBreakpoints(fAdded.toArray(new IBreakpoint[fAdded.size()]), false);
				} catch (CoreException e) {
					DebugPlugin.log(e);
				}
			}
			if (!fChanged.isEmpty()) {
				fireUpdate(fChanged, fChangedDeltas, CHANGED);
			}
			reset();
		}

		/**
		 * @see IResourceDeltaVisitor#visit(IResourceDelta)
		 */
		@Override
		public boolean visit(IResourceDelta delta) {
			if (delta == null) {
				return false;
			}
			if (0 != (delta.getFlags() & IResourceDelta.OPEN) && 0 == (delta.getFlags() & IResourceDelta.MOVED_FROM)) {
				handleProjectResourceOpenStateChange(delta.getResource());
				return false;
			}
			IMarkerDelta[] markerDeltas= delta.getMarkerDeltas();
			for (int i= 0; i < markerDeltas.length; i++) {
				IMarkerDelta markerDelta= markerDeltas[i];
				if (markerDelta.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
					switch (markerDelta.getKind()) {
						case IResourceDelta.ADDED :
							handleAddBreakpoint(delta, markerDelta.getMarker(), markerDelta);
							break;
						case IResourceDelta.REMOVED :
							handleRemoveBreakpoint(markerDelta.getMarker());
							break;
						case IResourceDelta.CHANGED :
							handleChangeBreakpoint(markerDelta.getMarker(), markerDelta);
							break;
						default:
							break;
					}
				}
			}

			return true;
		}

		/**
		 * Wrapper for handling adds
		 * @param rDelta the {@link IResourceDelta}
		 * @param marker the new {@link IMarker}
		 * @param mDelta the accompanying {@link IMarkerDelta}
		 */
		protected void handleAddBreakpoint(IResourceDelta rDelta, IMarker marker, IMarkerDelta mDelta) {
			if (0 != (rDelta.getFlags() & IResourceDelta.MOVED_FROM)) {
				// This breakpoint has actually been moved - already removed
				// from the Breakpoint manager during the remove callback.
				// Schedule the marker associated with the new resource for deletion.
				if (getBreakpoint(marker) == null) {
					fMoved.add(marker);
				}
			} else {
				// check if the an add & change have be combined into one add notification
				synchronized (fPostChangMarkersChanged) {
					if (fPostChangMarkersChanged.contains(marker)) {
						handleChangeBreakpoint(marker, mDelta);
						fPostChangMarkersChanged.remove(marker);
					} else if (marker.getAttribute(DebugPlugin.ATTR_BREAKPOINT_IS_DELETED, false) && getBreakpoint(marker) == null) {
						try { /*
							 * There may be breakpoints with matching resource
							 * and same line number
							 */
							IBreakpoint breakpoint = findMatchingBreakpoint(marker);
							if (breakpoint != null) {
								removeBreakpoint(breakpoint, true);
							}
							fAdded.add(createBreakpoint(marker));
						} catch (CoreException e) {
							DebugPlugin.log(e);
						}
					}
					fPostBuildMarkersAdded.add(marker);
				}
			}
		}

		/**
		 * To find a breakpoint with matching marker resources and line number.
		 *
		 * @param marker the {@link IMarker} for which existing breakpoint is
		 *            retrieved
		 * @return matching breakpoint if exists else return <code>null</code>
		 */
		private IBreakpoint findMatchingBreakpoint(IMarker marker) {
			Vector<IBreakpoint> breakpoints = getBreakpoints0();
			try {
				Integer line = (Integer) marker.getAttribute(IMarker.LINE_NUMBER);
				for (int i = 0; i < breakpoints.size(); i++) {
					IBreakpoint breakpoint = breakpoints.get(i);
					IMarker bpMarker = breakpoint.getMarker();
					if (bpMarker != null && marker.getResource().equals(bpMarker.getResource()) && bpMarker.getAttribute(IMarker.LINE_NUMBER, -1) == (line == null ? -1 : line.intValue())) {
						return breakpoint;
					}
				}
			} catch (CoreException e) {
				e.printStackTrace();
			}
			return null;
		}

		/**
		 * Wrapper for handling removes
		 * @param marker the {@link IMarker}
		 */
		protected void handleRemoveBreakpoint(IMarker marker) {
			synchronized (fPostChangMarkersChanged) {
				fPostChangMarkersChanged.remove(marker);
				fPostBuildMarkersAdded.remove(marker);
			}
			IBreakpoint breakpoint= getBreakpoint(marker);
			if (breakpoint != null) {
				fRemoved.add(breakpoint);
			}
		}

		/**
		 * Wrapper for handling changes
		 * @param marker the {@link IMarker} that was changed
		 * @param delta the {@link IMarkerDelta}
		 */
		protected void handleChangeBreakpoint(IMarker marker, IMarkerDelta delta) {
			IBreakpoint breakpoint= getBreakpoint(marker);
			if (breakpoint != null && isRegistered(breakpoint) && !isChangeSuppressed(breakpoint)) {
				fChanged.add(breakpoint);
				fChangedDeltas.add(delta);
			}
		}

		/**
		 * A project has been opened or closed.  Updates the breakpoints for
		 * that project
		 * @param project the {@link IProject} that was changed
		 */
		private void handleProjectResourceOpenStateChange(final IResource project) {
			if (!project.isAccessible()) {
				//closed
				for (@SuppressWarnings("unchecked") IBreakpoint breakpoint : (Vector<IBreakpoint>) getBreakpoints0().clone()) {
					IResource markerResource= breakpoint.getMarker().getResource();
					if (project.getFullPath().isPrefixOf(markerResource.getFullPath())) {
						fRemoved.add(breakpoint);
					}
				}
				return;
			}
			try {
				loadBreakpoints(project, true);
			} catch (CoreException e) {
				DebugPlugin.log(e);
			}
		}
	}

	/**
	 * @see IBreakpointManager#addBreakpointListener(IBreakpointListener)
	 */
	@Override
	public void addBreakpointListener(IBreakpointListener listener) {
		fBreakpointListeners.add(listener);
	}

	/**
	 * @see IBreakpointManager#removeBreakpointListener(IBreakpointListener)
	 */
	@Override
	public void removeBreakpointListener(IBreakpointListener listener) {
		fBreakpointListeners.remove(listener);
	}

	/**
	 * Notifies listeners of the adds/removes/changes
	 *
	 * @param breakpoints associated breakpoints
	 * @param deltas or <code>null</code>
	 * @param update type of change
	 */
	private void fireUpdate(List<IBreakpoint> breakpoints, List<IMarkerDelta> deltas, int update) {
		if (breakpoints.isEmpty()) {
			return;
		}
		IBreakpoint[] bpArray = breakpoints.toArray(new IBreakpoint[breakpoints.size()]);
		IMarkerDelta[] deltaArray = new IMarkerDelta[bpArray.length];
		if (deltas != null) {
			deltaArray = deltas.toArray(deltaArray);
		}
		// single listeners
		getBreakpointNotifier().notify(bpArray, deltaArray, update);

		// plural listeners
		getBreakpointsNotifier().notify(bpArray, deltaArray, update);
	}

	protected void setBreakpoints(Vector<IBreakpoint> breakpoints) {
		fBreakpoints = breakpoints;
	}

	/**
	 * @see IBreakpointManager#hasBreakpoints()
	 */
	@Override
	public boolean hasBreakpoints() {
		return !getBreakpoints0().isEmpty();
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointManager#addBreakpointListener(org.eclipse.debug.core.IBreakpointsListener)
	 */
	@Override
	public void addBreakpointListener(IBreakpointsListener listener) {
		fBreakpointsListeners.add(listener);
	}

	/**
	 * @see org.eclipse.debug.core.IBreakpointManager#removeBreakpointListener(org.eclipse.debug.core.IBreakpointsListener)
	 */
	@Override
	public void removeBreakpointListener(IBreakpointsListener listener) {
		fBreakpointsListeners.remove(listener);
	}

	private BreakpointNotifier getBreakpointNotifier() {
		return new BreakpointNotifier();
	}

	/**
	 * Notifies breakpoint listener (single breakpoint) in a safe runnable to
	 * handle exceptions.
	 */
	class BreakpointNotifier implements ISafeRunnable {

		private IBreakpointListener fListener;
		private int fType;
		private IMarkerDelta fDelta;
		private IBreakpoint fBreakpoint;

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
			IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during breakpoint change notification.", exception);  //$NON-NLS-1$
			DebugPlugin.log(status);
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			switch (fType) {
				case ADDED:
					fListener.breakpointAdded(fBreakpoint);
					break;
				case REMOVED:
					fListener.breakpointRemoved(fBreakpoint, fDelta);
					break;
				case CHANGED:
					fListener.breakpointChanged(fBreakpoint, fDelta);
					break;
				default:
					break;
			}
		}

		/**
		 * Notifies the listeners of the add/change/remove
		 *
		 * @param breakpoints the breakpoints that changed
		 * @param deltas the deltas associated with the change
		 * @param update the type of change
		 */
		public void notify(IBreakpoint[] breakpoints, IMarkerDelta[] deltas, int update) {
			fType = update;
			for (IBreakpointListener iBreakpointListener : fBreakpointListeners) {
				fListener = iBreakpointListener;
				for (int j = 0; j < breakpoints.length; j++) {
					fBreakpoint = breakpoints[j];
					fDelta = deltas[j];
                    SafeRunner.run(this);
				}
			}
			fListener = null;
			fDelta = null;
			fBreakpoint = null;
		}
	}

	private BreakpointsNotifier getBreakpointsNotifier() {
		return new BreakpointsNotifier();
	}

	/**
	 * Notifies breakpoint listener (multiple breakpoints) in a safe runnable to
	 * handle exceptions.
	 */
	class BreakpointsNotifier implements ISafeRunnable {

		private IBreakpointsListener fListener;
		private int fType;
		private IMarkerDelta[] fDeltas;
		private IBreakpoint[] fNotifierBreakpoints;

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
			IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during breakpoint change notification.", exception);  //$NON-NLS-1$
			DebugPlugin.log(status);
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			switch (fType) {
				case ADDED:
					fListener.breakpointsAdded(fNotifierBreakpoints);
					break;
				case REMOVED:
					fListener.breakpointsRemoved(fNotifierBreakpoints, fDeltas);
					break;
				case CHANGED:
					fListener.breakpointsChanged(fNotifierBreakpoints, fDeltas);
					break;
				default:
					break;
			}
		}

		/**
		 * Notifies the listeners of the adds/changes/removes
		 *
		 * @param breakpoints the breakpoints that changed
		 * @param deltas the deltas associated with the changed breakpoints
		 * @param update the type of change
		 */
		public void notify(IBreakpoint[] breakpoints, IMarkerDelta[] deltas, int update) {
			fType = update;
			fNotifierBreakpoints = breakpoints;
			fDeltas = deltas;
			for (IBreakpointsListener iBreakpointsListener : fBreakpointsListeners) {
				fListener = iBreakpointsListener;
				SafeRunner.run(this);
			}
			fDeltas = null;
			fNotifierBreakpoints = null;
			fListener = null;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#isEnabled()
	 */
	@Override
	public boolean isEnabled() {
		return Platform.getPreferencesService().getBoolean(DebugPlugin.getUniqueIdentifier(), IInternalDebugCoreConstants.PREF_BREAKPOINT_MANAGER_ENABLED_STATE, true, null);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#setEnabled(boolean)
	 */
	@Override
	public void setEnabled(final boolean enabled) {
        if (isEnabled() != enabled) {
        	Preferences.setBoolean(DebugPlugin.getUniqueIdentifier(), IInternalDebugCoreConstants.PREF_BREAKPOINT_MANAGER_ENABLED_STATE, enabled, null);
            IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
                @Override
				public void run(IProgressMonitor monitor) throws CoreException {
                    IBreakpoint[] breakpoints = getBreakpoints();
                    for (int i = 0; i < breakpoints.length; i++) {
                        IBreakpoint breakpoint = breakpoints[i];
                        // Touch the marker (but don't actually change anything) so that the icon in
                        // the editor ruler will be updated (editors listen to marker changes).
                        breakpoint.getMarker().setAttribute(IBreakpoint.ENABLED, breakpoint.isEnabled());
                    }
                }
            };
            try {
                ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE ,null);
            } catch (CoreException e) {
                DebugPlugin.log(e);
            }
    		new BreakpointManagerNotifier().notify(enabled);
        }
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#addBreakpointManagerListener(org.eclipse.debug.core.IBreakpointManagerListener)
	 */
	@Override
	public void addBreakpointManagerListener(IBreakpointManagerListener listener) {
		fBreakpointManagerListeners.add(listener);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#removeBreakpointManagerListener(org.eclipse.debug.core.IBreakpointManagerListener)
	 */
	@Override
	public void removeBreakpointManagerListener(IBreakpointManagerListener listener) {
		fBreakpointManagerListeners.remove(listener);
	}

	/**
	 * Notifies breakpoint manager listeners in a safe runnable to
	 * handle exceptions.
	 */
	class BreakpointManagerNotifier implements ISafeRunnable {

		private IBreakpointManagerListener fListener;
		private boolean fManagerEnabled;

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
			IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during breakpoint change notification.", exception);  //$NON-NLS-1$
			DebugPlugin.log(status);
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			fListener.breakpointManagerEnablementChanged(fManagerEnabled);
		}

		/**
		 * Notifies the listeners of the enabled state change
		 *
		 * @param enabled whether the manager is enabled
		 */
		public void notify(boolean enabled) {
			fManagerEnabled= enabled;
			for (IBreakpointManagerListener iBreakpointManagerListener : fBreakpointManagerListeners) {
				fListener = iBreakpointManagerListener;
                SafeRunner.run(this);
			}
			fListener = null;
		}
	}

	/**
	 * Notifies breakpoint manager listeners in a safe runnable to handle
	 * exceptions.
	 */
	class BreakpointManagerTriggerPointNotifier implements ISafeRunnable {

		private IBreakpointManagerListener fListener;
		private IBreakpoint fManagerTriggerpoint;

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
			IStatus status = new Status(IStatus.ERROR, DebugPlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "An exception occurred during breakpoint change notification.", exception); //$NON-NLS-1$
			DebugPlugin.log(status);
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			fListener.breakpointManagerTriggerPointChanged(fManagerTriggerpoint);
		}

		/**
		 * Notifies the listeners of the enabled state change
		 *
		 * @param triggerBreakpoint new breakpoint as trigger point
		 */
		public void notify(IBreakpoint triggerBreakpoint) {
			fManagerTriggerpoint = triggerBreakpoint;
			for (IBreakpointManagerListener iBreakpointManagerListener : fBreakpointManagerListeners) {
				fListener = iBreakpointManagerListener;
				SafeRunner.run(this);
			}
			fListener = null;
		}
	}

	class BreakpointManagerJob extends Job {

		private final IWorkspaceRunnable fRunnable;

		public BreakpointManagerJob (IWorkspaceRunnable wRunnable) {
			super("breakpoint manager job"); //$NON-NLS-1$
			fRunnable= wRunnable;
			setSystem(true);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		protected IStatus run(IProgressMonitor monitor) {
			try {
				getWorkspace().run(fRunnable, null, 0, null);
			} catch (CoreException ce) {
				DebugPlugin.log(ce);
			}
			return new Status(IStatus.OK, DebugPlugin.getUniqueIdentifier(), IStatus.OK, "", null); //$NON-NLS-1$
		}
	}

    /* (non-Javadoc)
     * @see org.eclipse.debug.core.IBreakpointManager#getTypeName(org.eclipse.debug.core.model.IBreakpoint)
     */
    @Override
	public String getTypeName(IBreakpoint breakpoint) {
        String typeName= null;
        IMarker marker = breakpoint.getMarker();
        if (marker != null) {
            try {
                IConfigurationElement element = fBreakpointExtensions.get(marker.getType());
                if (element != null) {
                    typeName= element.getAttribute(IConfigurationElementConstants.NAME);
                }
            }
            catch (CoreException e) {}
        }
        return typeName;
    }

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#getImportParticipants(java.lang.String)
	 */
	@Override
	public IBreakpointImportParticipant[] getImportParticipants(String markertype) throws CoreException {
		initializeImportParticipants();
		ArrayList<BreakpointImportParticipantDelegate> list = fImportParticipants.get(markertype);
		if(list == null) {
			return new IBreakpointImportParticipant[] {fDefaultParticipant};
		}
		IBreakpointImportParticipant[] participants = new IBreakpointImportParticipant[list.size()];
		BreakpointImportParticipantDelegate delegate = null;
		for(int i = 0; i < list.size(); i++) {
			delegate = list.get(i);
			participants[i] = delegate.getDelegate();
		}
		if(participants.length == 0) {
			return new IBreakpointImportParticipant[] {fDefaultParticipant};
		}
		return participants;
	}

	/**
	 * Initializes the cache of breakpoint import participants. Does no work if the cache
	 * has already been initialized
	 */
	private synchronized void initializeImportParticipants() {
		if(fImportParticipants == null) {
			fImportParticipants = new HashMap<String, ArrayList<BreakpointImportParticipantDelegate>>();
			fDefaultParticipant = new DefaultImportParticipant();
			IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_BREAKPOINT_IMPORT_PARTICIPANTS);
			IConfigurationElement[] elements = ep.getConfigurationElements();
			String type = null;
			ArrayList<BreakpointImportParticipantDelegate> list = null;
			for(int i = 0; i < elements.length; i++) {
				type = elements[i].getAttribute(IConfigurationElementConstants.TYPE);
				if(type != null) {
					list = fImportParticipants.get(type);
					if(list == null) {
						list = new ArrayList<BreakpointImportParticipantDelegate>();
						fImportParticipants.put(type, list);
					}
					list.add(new BreakpointImportParticipantDelegate(elements[i]));
				}
			}
		}
	}

	@Override
	public IBreakpoint[] getTriggerBreakpoints() {
		return fTriggerPointBreakpointList.toArray(new IBreakpoint[0]);
	}

	@Override
	public void addTriggerBreakpoint(IBreakpoint triggerBreakpoint) throws CoreException {
		if (triggerBreakpoint == null) {
			return;
		}
		fTriggerPointBreakpointList.add(triggerBreakpoint);
		new BreakpointManagerTriggerPointNotifier().notify(triggerBreakpoint);
	}

	@Override
	public void removeTriggerBreakpoint(IBreakpoint breakpoint) throws CoreException {
		if (breakpoint != null) {
			fTriggerPointBreakpointList.remove(breakpoint);
		}
	}

	@Override
	public void removeAllTriggerpoints() throws CoreException {
		IBreakpoint[] triggerPointBreakpointList = fTriggerPointBreakpointList.toArray(new IBreakpoint[0]);
		for (IBreakpoint iBreakpoint : triggerPointBreakpointList) {
			iBreakpoint.setTriggerPoint(false);
			iBreakpoint.setTriggerPointActive(false);
		}
		refreshTriggerpointDisplay();
	}

	@Override
	public boolean canSupendOnBreakpoint() {
		if (fTriggerPointBreakpointList.isEmpty()) {
			return true;
		}
		for (IBreakpoint iBreakpoint : fTriggerPointBreakpointList) {
			try {
				if (iBreakpoint.isTriggerPointActive()) {
					return false;
				}
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
		return true;
	}


	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointManager#revisitTriggerpoints()
	 * This version of implementation deactivate all the active trigger points
	 */
	@Override
	public void deActivateTriggerpoints(IBreakpoint[] triggerointList) {
		if (triggerointList == null) {
			triggerointList = fTriggerPointBreakpointList.toArray(new IBreakpoint[0]);
		}
		for (IBreakpoint iBreakpoint : triggerointList) {
			try {
				if (iBreakpoint.isTriggerPointActive()) {
					iBreakpoint.setTriggerPointActive(false);
				}
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
		refreshTriggerpointDisplay();
	}

	@Override
	public void refreshTriggerpointDisplay() {
		IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
			@Override
			public void run(IProgressMonitor monitor) throws CoreException {
				IBreakpoint[] breakpoints = getBreakpoints();
				for (int i = 0; i < breakpoints.length; i++) {
					IBreakpoint breakpoint = breakpoints[i];
					// Touch the marker (but don't actually change anything) so
					// that the icon in
					// the editor ruler will be updated (editors listen to
					// marker changes).
					breakpoint.getMarker().setAttribute(IBreakpoint.ENABLED, breakpoint.isEnabled());
				}
			}
		};
		try {
			ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, null);
		} catch (CoreException e) {
			DebugPlugin.log(e);
		}
	}
}

