/*******************************************************************************
 * 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.jdt.internal.debug.core.breakpoints;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.model.Breakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaBreakpointListener;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.debug.core.IJDIEventListener;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIObjectValue;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.eclipse.jdt.internal.debug.core.model.JDIType;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.event.ClassPrepareEvent;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.LocatableEvent;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;

public abstract class JavaBreakpoint extends Breakpoint implements IJavaBreakpoint, IJDIEventListener, IDebugEventSetListener {

	/**
	 * Breakpoint attribute storing the expired value (value
	 * <code>"org.eclipse.jdt.debug.core.expired"</code>). This attribute is
	 * stored as a <code>boolean</code>. Once a hit count has been reached, a
	 * breakpoint is considered to be "expired".
	 */
	protected static final String EXPIRED = "org.eclipse.jdt.debug.core.expired"; //$NON-NLS-1$
	/**
	 * Breakpoint attribute storing a breakpoint's hit count value (value
	 * <code>"org.eclipse.jdt.debug.core.hitCount"</code>). This attribute is
	 * stored as an <code>int</code>.
	 */
	protected static final String HIT_COUNT = "org.eclipse.jdt.debug.core.hitCount"; //$NON-NLS-1$
	/**
	 * Breakpoint attribute storing the number of debug targets a breakpoint is
	 * installed in (value
	 * <code>"org.eclipse.jdt.debug.core.installCount"</code>). This attribute
	 * is a <code>int</code>.
	 */
	protected static final String INSTALL_COUNT = "org.eclipse.jdt.debug.core.installCount"; //$NON-NLS-1$

	/**
	 * Breakpoint attribute storing the fully qualified name of the type this
	 * breakpoint is located in. (value
	 * <code>"org.eclipse.jdt.debug.core.typeName"</code>). This attribute is a
	 * <code>String</code>.
	 */
	protected static final String TYPE_NAME = "org.eclipse.jdt.debug.core.typeName"; //$NON-NLS-1$

	/**
	 * Breakpoint attribute storing suspend policy code for this breakpoint.
	 * (value <code>"org.eclipse.jdt.debug.core.suspendPolicy</code>). This
	 * attribute is an <code>int</code> corresponding to
	 * <code>IJavaBreakpoint.SUSPEND_VM</code> or
	 * <code>IJavaBreakpoint.SUSPEND_THREAD</code>.
	 */
	protected static final String SUSPEND_POLICY = "org.eclipse.jdt.debug.core.suspendPolicy"; //$NON-NLS-1$

	/**
	 * Breakpoint attribute storing a comma delimited list of extension
	 * identifiers of breakpoint listeners. The listeners will be notified in
	 * the order specified in the list.
	 *
	 * @since 3.5
	 */
	public static final String BREAKPOINT_LISTENERS = JDIDebugPlugin.EXTENSION_POINT_JAVA_BREAKPOINT_LISTENERS;
	/**
	 * Breakpoint attribute storing the expired value of trigger point (value
	 * <code>"org.eclipse.jdt.debug.core.expiredTriggerPoint"</code>). This attribute is
	 * stored as a <code>boolean</code>. Once a trigger point is hit, a
	 * breakpoint is considered to be "expired" as trigger point for the session.
	 *
	 * @since 3.11
	 */
	public static final String EXPIRED_TRIGGER_POINT = "org.eclipse.jdt.debug.core.expiredTriggerPoint"; //$NON-NLS-1$

	/**
	 * Stores the collection of requests that this breakpoint has installed in
	 * debug targets. key: a debug target value: the requests this breakpoint
	 * has installed in that target
	 */
	protected HashMap<JDIDebugTarget, List<EventRequest>> fRequestsByTarget;

	/**
	 * The list of threads (ThreadReference objects) in which this breakpoint
	 * will suspend, associated with the target in which each thread exists
	 * (JDIDebugTarget). key: targets the debug targets (IJavaDebugTarget)
	 * value: thread the filtered thread (IJavaThread) in the given target
	 */
	protected Map<JDIDebugTarget, IJavaThread> fFilteredThreadsByTarget;

	/**
	 * Stores the type name that this breakpoint was last installed in. When a
	 * breakpoint is created, the TYPE_NAME attribute assigned to it is that of
	 * its top level enclosing type. When installed, the type may actually be an
	 * inner type. We need to keep track of the type type the breakpoint was
	 * installed in, in case we need to re-install the breakpoint for HCR (i.e.
	 * in case an inner type is HCR'd).
	 */
	protected String fInstalledTypeName = null;

	/**
	 * List of targets in which this breakpoint is installed. Used to prevent
	 * firing of more than one install notification when a breakpoint's requests
	 * are re-created.
	 */
	protected Set<IJavaDebugTarget> fInstalledTargets = null;

	/**
	 * List of active instance filters for this breakpoint (list of
	 * <code>IJavaObject</code>).
	 */
	protected List<IJavaObject> fInstanceFilters = null;

	/**
	 * List of breakpoint listener identifiers corresponding to breakpoint
	 * listener extensions. Listeners are cached with the breakpoint object such
	 * that they can be notified when a breakpoint is removed.
	 */
	private List<String> fBreakpointListenerIds = null;

	/**
	 * Empty instance filters array.
	 */
	protected static final IJavaObject[] fgEmptyInstanceFilters = new IJavaObject[0];

	/**
	 * Property identifier for a breakpoint object on an event request
	 */
	public static final String JAVA_BREAKPOINT_PROPERTY = "org.eclipse.jdt.debug.breakpoint"; //$NON-NLS-1$

	/**
	 * JavaBreakpoint attributes
	 */
	protected static final String[] fgExpiredEnabledAttributes = new String[] {
			EXPIRED, ENABLED };

	public JavaBreakpoint() {
		fRequestsByTarget = new HashMap<>(1);
		fFilteredThreadsByTarget = new HashMap<>(1);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier()
	 */
	@Override
	public String getModelIdentifier() {
		return JDIDebugModel.getPluginIdentifier();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.debug.core.model.Breakpoint#setMarker(org.eclipse.core.resources
	 * .IMarker)
	 */
	@Override
	public void setMarker(IMarker marker) throws CoreException {
		super.setMarker(marker);
		configureAtStartup();
	}

	/**
	 * Add this breakpoint to the breakpoint manager, or sets it as
	 * unregistered.
	 */
	protected void register(boolean register) throws CoreException {
		DebugPlugin plugin = DebugPlugin.getDefault();
		if (plugin != null && register) {
			plugin.getBreakpointManager().addBreakpoint(this);
		} else {
			setRegistered(false);
		}
	}

	/**
	 * Add the given event request to the given debug target. If the request is
	 * the breakpoint request associated with this breakpoint, increment the
	 * install count.
	 */
	protected void registerRequest(EventRequest request, JDIDebugTarget target)
			throws CoreException {
		if (request == null) {
			return;
		}
		List<EventRequest> reqs = getRequests(target);
		if (reqs.isEmpty()) {
			fRequestsByTarget.put(target, reqs);
		}
		reqs.add(request);
		target.addJDIEventListener(this, request);
		// update the install attribute on the breakpoint
		if (!(request instanceof ClassPrepareRequest)) {
			incrementInstallCount();
			// notification
			fireInstalled(target);
		}
	}

	/**
	 * Returns a String corresponding to the reference type name to the top
	 * enclosing type in which this breakpoint is located or <code>null</code>
	 * if no reference type could be found.
	 */
	protected String getEnclosingReferenceTypeName() throws CoreException {
		String name = getTypeName();
		if (name != null) {
			int index = name.indexOf('$');
			if (index == -1) {
				return name;
			}
			return name.substring(0, index);
		}
		return null;
	}

	/**
	 * Returns the requests that this breakpoint has installed in the given
	 * target.
	 */
	protected ArrayList<EventRequest> getRequests(JDIDebugTarget target) {
		ArrayList<EventRequest> list = (ArrayList<EventRequest>) fRequestsByTarget.get(target);
		if (list == null) {
			list = new ArrayList<>(2);
		}
		return list;
	}

	/**
	 * Remove the given request from the given target. If the request is the
	 * breakpoint request associated with this breakpoint, decrement the install
	 * count.
	 */
	protected void deregisterRequest(EventRequest request, JDIDebugTarget target)
			throws CoreException {
		target.removeJDIEventListener(this, request);
		// A request may be getting de-registered because the breakpoint has
		// been deleted. It may be that this occurred because of a marker
		// deletion.
		// Don't try updating the marker (decrementing the install count) if
		// it no longer exists.
		if (!(request instanceof ClassPrepareRequest) && getMarker().exists()) {
			decrementInstallCount();
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.internal.debug.core.IJDIEventListener#handleEvent(com
	 * .sun.jdi.event.Event,
	 * org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
	 */
	@Override
	public boolean handleEvent(Event event, JDIDebugTarget target,
			boolean suspendVote, EventSet eventSet) {
		if (event instanceof ClassPrepareEvent) {
			return handleClassPrepareEvent((ClassPrepareEvent) event, target,
					suspendVote);
		}
		ThreadReference threadRef = ((LocatableEvent) event).thread();
		JDIThread thread = target.findThread(threadRef);
		if (thread == null) {
			thread = target.findThread(threadRef);
		}
		if (thread == null || thread.isIgnoringBreakpoints()) {
			return true;
		}
		return handleBreakpointEvent(event, thread, suspendVote);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.internal.debug.core.IJDIEventListener#eventSetComplete
	 * (com.sun.jdi.event.Event,
	 * org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget, boolean)
	 */
	@Override
	public void eventSetComplete(Event event, JDIDebugTarget target,
			boolean suspend, EventSet eventSet) {
		ThreadReference threadRef = null;
		if (event instanceof ClassPrepareEvent) {
			threadRef = ((ClassPrepareEvent) event).thread();
		} else if (event instanceof LocatableEvent) {
			threadRef = ((LocatableEvent) event).thread();
		}
		if (threadRef == null) {
			return;
		}
		JDIThread thread = target.findThread(threadRef);
		if (thread == null || thread.isIgnoringBreakpoints()) {
			return;
		}
		if (event instanceof ClassPrepareEvent) {
			classPrepareComplete(event, thread, suspend, eventSet);
		} else {
			thread.completeBreakpointHandling(this, suspend, true, eventSet);
		}
	}

	/**
	 * Call-back that the class prepare event has completed
	 * @param event the event
	 * @param thread the thread that sent the event
	 * @param suspend if the the thread was suspended
	 * @param eventSet the event set context
	 */
	protected void classPrepareComplete(Event event, JDIThread thread, boolean suspend, EventSet eventSet) {
		// resume the thread if this is a class load event to install a deferred
		// breakpoint (and the vote is to resume)
		if (thread != null && !suspend) {
			thread.resumedFromClassPrepare();
		}
	}

	/**
	 * Handle the given class prepare event, which was generated by the class
	 * prepare event installed in the given target by this breakpoint.
	 *
	 * If the class which has been loaded is a class in which this breakpoint
	 * should install, create a breakpoint request for that class.
	 * @param event the event
	 * @param target the target
	 * @param suspendVote the current suspend vote
	 * @return is the thread should suspend or not
	 */
	public boolean handleClassPrepareEvent(ClassPrepareEvent event, JDIDebugTarget target, boolean suspendVote) {
		try {
			if (!installableReferenceType(event.referenceType(), target)) {
				// Don't install this breakpoint in an
				// inappropriate type
				return true;
			}
			createRequest(target, event.referenceType());
		} catch (CoreException e) {
			JDIDebugPlugin.log(e);
		}
		return true;
	}

	/**
	 * @see IJDIEventListener#handleEvent(Event, JDIDebugTarget)
	 *
	 *      Handle the given event, which was generated by the breakpoint
	 *      request installed in the given target by this breakpoint.
	 */
	public boolean handleBreakpointEvent(Event event, JDIThread thread,
			boolean suspendVote) {
		expireHitCount(event);
		disableTriggerPoint(event);
		return !suspend(thread, suspendVote); // Resume if suspend fails
	}

	/**
	 * Delegates to the given thread to suspend, and returns whether the thread
	 * suspended It is possible that the thread will not suspend as directed by
	 * a Java breakpoint listener.
	 *
	 * @see IJavaBreakpointListener#breakpointHit(IJavaThread, IJavaBreakpoint)
	 */
	protected boolean suspend(JDIThread thread, boolean suspendVote) {
		return thread.handleSuspendForBreakpoint(this, suspendVote);
	}

	/**
	 * Returns whether the given reference type is appropriate for this
	 * breakpoint to be installed in the given target. Query registered
	 * breakpoint listeners.
	 */
	protected boolean installableReferenceType(ReferenceType type,
			JDIDebugTarget target) throws CoreException {
		String installableType = getTypeName();
		if (installableType == null ) {
			return false;
		}
		String queriedType = type.name();
		if( queriedType == null) {
			return false;
		}
		int index = queriedType.indexOf('<');
		if (index != -1) {
			queriedType = queriedType.substring(0, index);
		}
		if (installableType.equals(queriedType)) {
			return queryInstallListeners(target, type);
		}
		index = queriedType.indexOf('$', 0);
		if (index == -1) {
			return false;
		}
		if (installableType.regionMatches(0, queriedType, 0, index)) {
			return queryInstallListeners(target, type);
		}
		return false;
	}

	/**
	 * Called when a breakpoint event is encountered. Expires the hit count in
	 * the event's request and updates the marker.
	 *
	 * @param event
	 *            the event whose request should have its hit count expired or
	 *            <code>null</code> to only update the breakpoint marker.
	 */
	protected void expireHitCount(Event event) {
		Integer requestCount = null;
		EventRequest request = null;
		if (event != null) {
			request = event.request();
			requestCount = (Integer) request.getProperty(HIT_COUNT);
		}
		if (requestCount != null) {
			if (request != null) {
				request.putProperty(EXPIRED, Boolean.TRUE);
			}
			try {
				setAttributes(fgExpiredEnabledAttributes, new Object[] {
						Boolean.TRUE, Boolean.FALSE });
				// make a note that we auto-disabled this breakpoint.
			} catch (CoreException ce) {
				JDIDebugPlugin.log(ce);
			}
		}
	}

	protected void disableTriggerPoint(Event event) {
		try{
			if (isTriggerPoint() && isEnabled()) {
					DebugPlugin.getDefault().getBreakpointManager().enableTriggerPoints(null, false);
					// make a note that we auto-disabled the trigger point for this breakpoint.
					// we re enable it at cleanup of JDITarget
				}
			}catch (CoreException ce) {
				JDIDebugPlugin.log(ce);
			}

	}

	/**
	 * Returns whether this breakpoint should be "skipped". Breakpoints are
	 * skipped if the breakpoint manager is disabled and the breakpoint is
	 * registered with the manager
	 *
	 * @return whether this breakpoint should be skipped
	 */
	public boolean shouldSkipBreakpoint() throws CoreException {
		DebugPlugin plugin = DebugPlugin.getDefault();
		return plugin != null && isRegistered()
				&& !plugin.getBreakpointManager().isEnabled();
	}

	/**
	 * Attempts to create a breakpoint request for this breakpoint in the given
	 * reference type in the given target.
	 *
	 * @return Whether a request was created
	 */
	protected boolean createRequest(JDIDebugTarget target, ReferenceType type)
			throws CoreException {
		if (shouldSkipBreakpoint()) {
			return false;
		}
		EventRequest[] requests = newRequests(target, type);
		if (requests == null) {
			return false;
		}
		fInstalledTypeName = type.name();
		for (EventRequest request : requests) {
			registerRequest(request, target);
		}
		return true;
	}

	/**
	 * Configure a breakpoint request with common properties:
	 * <ul>
	 * <li><code>JAVA_BREAKPOINT_PROPERTY</code></li>
	 * <li><code>HIT_COUNT</code></li>
	 * <li><code>EXPIRED</code></li>
	 * </ul>
	 * and sets the suspend policy of the request to suspend the event thread.
	 */
	protected void configureRequest(EventRequest request, JDIDebugTarget target)
			throws CoreException {
		request.setSuspendPolicy(getJDISuspendPolicy());
		request.putProperty(JAVA_BREAKPOINT_PROPERTY, this);
		configureRequestThreadFilter(request, target);
		configureRequestHitCount(request);
		configureInstanceFilters(request, target);
		// Important: only enable a request after it has been configured
		updateEnabledState(request, target);
	}

	/**
	 * Adds an instance filter to the given request. Since the implementation is
	 * request specific, subclasses must override.
	 *
	 * @param request
	 * @param object
	 *            instance filter
	 */
	protected abstract void addInstanceFilter(EventRequest request,
			ObjectReference object);

	/**
	 * Configure the thread filter property of the given request.
	 */
	protected void configureRequestThreadFilter(EventRequest request,
			JDIDebugTarget target) {
		IJavaThread thread = fFilteredThreadsByTarget.get(target);
		if (thread == null || (!(thread instanceof JDIThread))) {
			return;
		}
		setRequestThreadFilter(request,
				((JDIThread) thread).getUnderlyingThread());
	}

	/**
	 * Configure the given request's hit count
	 */
	protected void configureRequestHitCount(EventRequest request)
			throws CoreException {
		int hitCount = getHitCount();
		if (hitCount > 0) {
			request.addCountFilter(hitCount);
			request.putProperty(HIT_COUNT, new Integer(hitCount));
		}
	}

	protected void configureInstanceFilters(EventRequest request,
			JDIDebugTarget target) {
		if (fInstanceFilters != null && !fInstanceFilters.isEmpty()) {
			Iterator<IJavaObject> iter = fInstanceFilters.iterator();
			while (iter.hasNext()) {
				IJavaObject object = iter.next();
				if (object.getDebugTarget().equals(target)) {
					addInstanceFilter(request,
							((JDIObjectValue) object).getUnderlyingObject());
				}
			}
		}
	}

	/**
	 * Creates, installs, and returns all event requests for this breakpoint in
	 * the given reference type and and target.
	 *
	 * @return the event requests created or <code>null</code> if creation
	 *         failed
	 */
	protected abstract EventRequest[] newRequests(JDIDebugTarget target,
			ReferenceType type) throws CoreException;

	/**
	 * Add this breakpoint to the given target. After it has been added to the
	 * given target, this breakpoint will suspend execution of that target as
	 * appropriate.
	 */
	public void addToTarget(JDIDebugTarget target) throws CoreException {
		fireAdding(target);
		createRequests(target);
	}

	/**
	 * Creates event requests for the given target
	 */
	protected void createRequests(JDIDebugTarget target) throws CoreException {
		if (target.isTerminated() || shouldSkipBreakpoint()) {
			return;
		}
		String referenceTypeName = getTypeName();
		String enclosingTypeName = getEnclosingReferenceTypeName();
		if (referenceTypeName == null || enclosingTypeName == null) {
			return;
		}
		// create request to listen to class loads
		if (referenceTypeName.indexOf('$') == -1) {
			registerRequest(
					target.createClassPrepareRequest(enclosingTypeName), target);
			// register to ensure we hear about local and anonymous inner
			// classes
			registerRequest(
					target.createClassPrepareRequest(enclosingTypeName + "$*"), target); //$NON-NLS-1$
		} else {
			registerRequest(
					target.createClassPrepareRequest(referenceTypeName), target);
			// register to ensure we hear about local and anonymous inner
			// classes
			registerRequest(target.createClassPrepareRequest(enclosingTypeName
					+ "$*", referenceTypeName), target); //$NON-NLS-1$
		}

		// create breakpoint requests for each class currently loaded
		List<ReferenceType> classes = target.jdiClassesByName(referenceTypeName);
		if (classes.isEmpty() && enclosingTypeName.equals(referenceTypeName)) {
			return;
		}

		boolean success = false;
		Iterator<ReferenceType> iter = classes.iterator();
		while (iter.hasNext()) {
			ReferenceType type = iter.next();
			if (createRequest(target, type)) {
				success = true;
			}
		}

		if (!success) {
			addToTargetForLocalType(target, enclosingTypeName);
		}
	}

	/**
	 * Local types (types defined in methods) are handled specially due to the
	 * different types that the local type is associated with as well as the
	 * performance problems of using ReferenceType#nestedTypes. From the Java
	 * model perspective a local type is defined within a method of a type.
	 * Therefore the type of a breakpoint placed in a local type is the type
	 * that encloses the method where the local type was defined. The local type
	 * is enclosed within the top level type according to the VM. So if "normal"
	 * attempts to create a request when a breakpoint is being added to a target
	 * fail, we must be dealing with a local type and therefore resort to
	 * looking up all of the nested types of the top level enclosing type.
	 *
	 * @param target the target
	 * @param enclosingTypeName the type name of the enclosing type
	 * @throws CoreException if something bad happens
	 */
	protected void addToTargetForLocalType(JDIDebugTarget target, String enclosingTypeName) throws CoreException {
		List<ReferenceType> classes = target.jdiClassesByName(enclosingTypeName);
		for(ReferenceType type : classes) {
			for(ReferenceType nestedType : type.nestedTypes()) {
				if (createRequest(target, nestedType)) {
					break;
				}
			}
		}
	}

	/**
	 * Returns the JDI suspend policy that corresponds to this breakpoint's
	 * suspend policy
	 *
	 * @return the JDI suspend policy that corresponds to this breakpoint's
	 *         suspend policy
	 * @exception CoreException
	 *                if unable to access this breakpoint's suspend policy
	 *                setting
	 */
	protected int getJDISuspendPolicy() throws CoreException {
		int breakpointPolicy = getSuspendPolicy();
		if (breakpointPolicy == IJavaBreakpoint.SUSPEND_THREAD) {
			return EventRequest.SUSPEND_EVENT_THREAD;
		}
		return EventRequest.SUSPEND_ALL;
	}

	/**
	 * returns the default suspend policy based on the pref setting on the
	 * Java-Debug pref page
	 *
	 * @return the default suspend policy
	 * @since 3.2
	 */
	protected int getDefaultSuspendPolicy() {
		return Platform.getPreferencesService().getInt(
				JDIDebugPlugin.getUniqueIdentifier(),
				JDIDebugPlugin.PREF_DEFAULT_BREAKPOINT_SUSPEND_POLICY,
				IJavaBreakpoint.SUSPEND_THREAD,
				null);
	}

	/**
	 * Returns whether the hitCount of this breakpoint is equal to the hitCount
	 * of the associated request.
	 */
	protected boolean hasHitCountChanged(EventRequest request)
			throws CoreException {
		int hitCount = getHitCount();
		Integer requestCount = (Integer) request.getProperty(HIT_COUNT);
		int oldCount = -1;
		if (requestCount != null) {
			oldCount = requestCount.intValue();
		}
		return hitCount != oldCount;
	}

	/**
	 * Removes this breakpoint from the given target.
	 */
	public void removeFromTarget(final JDIDebugTarget target)
			throws CoreException {
		removeRequests(target);
		Object removed = fFilteredThreadsByTarget.remove(target);
		boolean changed = removed != null;
		boolean markerExists = markerExists();
		if (!markerExists || (markerExists && getInstallCount() == 0)) {
			fInstalledTypeName = null;
		}

		// remove instance filters
		if (fInstanceFilters != null && !fInstanceFilters.isEmpty()) {
			for (int i = 0; i < fInstanceFilters.size(); i++) {
				IJavaObject object = fInstanceFilters.get(i);
				if (object.getDebugTarget().equals(target)) {
					fInstanceFilters.remove(i);
					changed = true;
				}
			}
		}

		// fire change notification if required
		if (changed) {
			fireChanged();
		}

		// notification
		fireRemoved(target);
	}

	/**
	 * Remove all requests that this breakpoint has installed in the given debug
	 * target.
	 */
	protected void removeRequests(final JDIDebugTarget target) throws CoreException {
		// removing was previously done is a workspace runnable, but that is
		// not possible since it can be a resource callback (marker deletion)
		// that causes a breakpoint to be removed
		ArrayList<EventRequest> requests = new ArrayList<>(getRequests(target));
		// Iterate over a copy of the requests since this list of requests
		// can be changed in other threads which would cause an
		// ConcurrentModificationException
		Iterator<EventRequest> iter = requests.iterator();
		EventRequest req;
		while (iter.hasNext()) {
			req = iter.next();
			try {
				if (target.isAvailable() && !isExpired(req)) {
					EventRequestManager manager = target
							.getEventRequestManager();
					if (manager != null) {
						manager.deleteEventRequest(req); // disable & remove
					}
				}
			} catch (VMDisconnectedException e) {
				if (target.isAvailable()) {
					JDIDebugPlugin.log(e);
				}
			} catch (RuntimeException e) {
				target.internalError(e);
			} finally {
				deregisterRequest(req, target);
			}
		}
		fRequestsByTarget.remove(target);
	}

	/**
	 * Update the enabled state of the given request in the given target, which
	 * is associated with this breakpoint. Set the enabled state of the request
	 * to the enabled state of this breakpoint.
	 */
	protected void updateEnabledState(EventRequest request,
			JDIDebugTarget target) throws CoreException {
		internalUpdateEnabledState(request, isEnabled(), target);
	}

	/**
	 * Set the enabled state of the given request to the given value, also
	 * taking into account instance filters.
	 */
	protected void internalUpdateEnabledState(EventRequest request,
			boolean enabled, JDIDebugTarget target) {
		if (request.isEnabled() != enabled) {
			// change the enabled state
			try {
				// if the request has expired, do not disable.
				// BreakpointRequests that have expired cannot be deleted.
				if (!isExpired(request)) {
					request.setEnabled(enabled);
				}
			} catch (VMDisconnectedException e) {
			} catch (RuntimeException e) {
				target.internalError(e);
			}
		}
	}

	/**
	 * Returns whether this breakpoint has expired.
	 */
	public boolean isExpired() throws CoreException {
		return ensureMarker().getAttribute(EXPIRED, false);
	}

	/**
	 * Returns whether the given request is expired
	 */
	protected boolean isExpired(EventRequest request) {
		Boolean requestExpired = (Boolean) request.getProperty(EXPIRED);
		if (requestExpired == null) {
			return false;
		}
		return requestExpired.booleanValue();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#isInstalled()
	 */
	@Override
	public boolean isInstalled() throws CoreException {
		return ensureMarker().getAttribute(INSTALL_COUNT, 0) > 0;
	}

	/**
	 * Increments the install count of this breakpoint
	 */
	protected void incrementInstallCount() throws CoreException {
		int count = getInstallCount();
		setAttribute(INSTALL_COUNT, count + 1);
	}

	/**
	 * Returns the <code>INSTALL_COUNT</code> attribute of this breakpoint or 0
	 * if the attribute is not set.
	 */
	public int getInstallCount() throws CoreException {
		return ensureMarker().getAttribute(INSTALL_COUNT, 0);
	}

	/**
	 * Returns whether this trigger breakpoint has expired.
	 */
	public boolean isTriggerPointExpired() throws CoreException {
		return ensureMarker().getAttribute(EXPIRED_TRIGGER_POINT, false);
	}

	/**
	 * Decrements the install count of this breakpoint.
	 */
	protected void decrementInstallCount() throws CoreException {
		int count = getInstallCount();
		if (count > 0) {
			setAttribute(INSTALL_COUNT, count - 1);
		}
		if (count == 1) {
			if (isExpired()) {
				// if breakpoint was auto-disabled, re-enable it
				setAttributes(fgExpiredEnabledAttributes, new Object[] {
						Boolean.FALSE, Boolean.TRUE });
			}
		}
	}

	/**
	 * Sets the type name in which to install this breakpoint.
	 */
	protected void setTypeName(String typeName) throws CoreException {
		setAttribute(TYPE_NAME, typeName);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getTypeName()
	 */
	@Override
	public String getTypeName() throws CoreException {
		if (fInstalledTypeName == null) {
			return ensureMarker().getAttribute(TYPE_NAME, null);
		}
		return fInstalledTypeName;
	}

	/**
	 * Resets the install count attribute on this breakpoint's marker to "0".
	 * Resets the expired attribute on all breakpoint markers to
	 * <code>false</code>. Resets the enabled attribute on the breakpoint marker
	 * to <code>true</code>. If a workbench crashes, the attributes could have
	 * been persisted in an incorrect state.
	 */
	private void configureAtStartup() throws CoreException {
		List<String> attributes = null;
		List<Object> values = new ArrayList<>(3);
		if (isInstalled()) {
			attributes = new ArrayList<>(3);
			attributes.add(INSTALL_COUNT);
			values.add(new Integer(0));
		}
		if (isExpired()) {
			if (attributes == null) {
				attributes = new ArrayList<>(3);
			}
			// if breakpoint was auto-disabled, re-enable it
			attributes.add(EXPIRED);
			values.add(Boolean.FALSE);
			attributes.add(ENABLED);
			values.add(Boolean.TRUE);
		}
		if (attributes != null) {
			String[] strAttributes = new String[attributes.size()];
			setAttributes(attributes.toArray(strAttributes), values.toArray());
		}
		String[] listeners = readBreakpointListeners();
		if (listeners.length > 0) {
			fBreakpointListenerIds = new ArrayList<>();
			for (String listener : listeners) {
				fBreakpointListenerIds.add(listener);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getHitCount()
	 */
	@Override
	public int getHitCount() throws CoreException {
		return ensureMarker().getAttribute(HIT_COUNT, -1);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setHitCount(int)
	 */
	@Override
	public void setHitCount(int count) throws CoreException {
		if (getHitCount() != count) {
			if (!isEnabled() && count > -1) {
				setAttributes(new String[] { ENABLED, HIT_COUNT, EXPIRED },
						new Object[] { Boolean.TRUE, new Integer(count),
								Boolean.FALSE });
			} else {
				setAttributes(new String[] { HIT_COUNT, EXPIRED },
						new Object[] { new Integer(count), Boolean.FALSE });
			}
			recreate();
		}
	}

	protected String getMarkerMessage(int hitCount, int suspendPolicy) {
		StringBuffer buff = new StringBuffer();
		if (hitCount > 0) {
			buff.append(MessageFormat
					.format(JDIDebugBreakpointMessages.JavaBreakpoint___Hit_Count___0___1,
							new Object[] { Integer.toString(hitCount) }));
			buff.append(' ');
		}
		String suspendPolicyString;
		if (suspendPolicy == IJavaBreakpoint.SUSPEND_THREAD) {
			suspendPolicyString = JDIDebugBreakpointMessages.JavaBreakpoint__suspend_policy__thread__1;
		} else {
			suspendPolicyString = JDIDebugBreakpointMessages.JavaBreakpoint__suspend_policy__VM__2;
		}

		buff.append(suspendPolicyString);
		return buff.toString();
	}

	/**
	 * Sets whether this breakpoint's hit count has expired.
	 */
	public void setExpired(boolean expired) throws CoreException {
		setAttribute(EXPIRED, expired);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getSuspendPolicy()
	 */
	@Override
	public int getSuspendPolicy() throws CoreException {
		return ensureMarker().getAttribute(SUSPEND_POLICY,
				IJavaBreakpoint.SUSPEND_THREAD);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#setSuspendPolicy(int)
	 */
	@Override
	public void setSuspendPolicy(int suspendPolicy) throws CoreException {
		if (getSuspendPolicy() != suspendPolicy) {
			setAttribute(SUSPEND_POLICY, suspendPolicy);
			recreate();
		}
	}

	/**
	 * Notifies listeners this breakpoint is to be added to the given target.
	 *
	 * @param target
	 *            debug target
	 */
	protected void fireAdding(IJavaDebugTarget target) {
		JDIDebugPlugin plugin = JDIDebugPlugin.getDefault();
		if (plugin != null) {
			plugin.fireBreakpointAdding(target, this);
		}
	}

	/**
	 * Notifies listeners this breakpoint has been removed from the given
	 * target.
	 *
	 * @param target
	 *            debug target
	 */
	protected void fireRemoved(IJavaDebugTarget target) {
		JDIDebugPlugin plugin = JDIDebugPlugin.getDefault();
		if (plugin != null) {
			plugin.fireBreakpointRemoved(target, this);
			setInstalledIn(target, false);
		}
	}

	/**
	 * Notifies listeners this breakpoint has been installed in the given
	 * target.
	 *
	 * @param target
	 *            debug target
	 */
	protected void fireInstalled(IJavaDebugTarget target) {
		JDIDebugPlugin plugin = JDIDebugPlugin.getDefault();
		if (plugin != null && !isInstalledIn(target)) {
			plugin.fireBreakpointInstalled(target, this);
			setInstalledIn(target, true);
		}
	}

	/**
	 * Returns whether this breakpoint is installed in the given target.
	 *
	 * @param target
	 * @return whether this breakpoint is installed in the given target
	 */
	protected boolean isInstalledIn(IJavaDebugTarget target) {
		return fInstalledTargets != null && fInstalledTargets.contains(target);
	}

	/**
	 * Sets this breakpoint as installed in the given target
	 *
	 * @param target
	 * @param installed
	 *            whether installed
	 */
	protected void setInstalledIn(IJavaDebugTarget target, boolean installed) {
		if (installed) {
			if (fInstalledTargets == null) {
				fInstalledTargets = new HashSet<>();
			}
			fInstalledTargets.add(target);
		} else {
			if (fInstalledTargets != null) {
				fInstalledTargets.remove(target);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaBreakpoint#setThreadFilter(org.eclipse
	 * .jdt.debug.core.IJavaThread)
	 */
	@Override
	public void setThreadFilter(IJavaThread thread) throws CoreException {
		if (!(thread.getDebugTarget() instanceof JDIDebugTarget)
				|| !(thread instanceof JDIThread)) {
			return;
		}
		JDIDebugTarget target = (JDIDebugTarget) thread.getDebugTarget();
		if (thread != fFilteredThreadsByTarget.put(target, thread)) {
			// recreate the breakpoint only if it is not the same thread

			// Other breakpoints set attributes on the underlying
			// marker and the marker changes are eventually
			// propagated to the target. The target then asks the
			// breakpoint to update its request. Since thread filters
			// are transient properties, they are not set on
			// the marker. Thus we must update the request
			// here.
			recreate(target);
			fireChanged();
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse
	 * .debug.core.DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (DebugEvent event : events) {
			if (event.getKind() == DebugEvent.TERMINATE) {
				Object source = event.getSource();
				if (!(source instanceof JDIThread)) {
					return;
				}
				try {
					cleanupForThreadTermination((JDIThread) source);
				} catch (VMDisconnectedException exception) {
					// Thread death often occurs at shutdown.
					// A VMDisconnectedException trying to
					// update the breakpoint request is
					// acceptable.
				}
			}
		}
	}

	/**
	 * Removes cached information relevant to this thread which has terminated.
	 *
	 * Remove thread filters for terminated threads
	 *
	 * Subclasses may override but need to call super.
	 */
	protected void cleanupForThreadTermination(JDIThread thread) {
		JDIDebugTarget target = (JDIDebugTarget) thread.getDebugTarget();
		try {
			if (thread == getThreadFilter(target)) {
				removeThreadFilter(target);
			}
		} catch (CoreException exception) {
			JDIDebugPlugin.log(exception);
		}
	}

	/**
	 * EventRequest does not support thread filters, so they can't be set
	 * generically here. However, each of the breakpoint subclasses of
	 * EventRequest do support thread filters. So subclasses can set thread
	 * filters on their specific request type.
	 */
	protected abstract void setRequestThreadFilter(EventRequest request,
			ThreadReference thread);

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaBreakpoint#getThreadFilter(org.eclipse
	 * .jdt.debug.core.IJavaDebugTarget)
	 */
	@Override
	public IJavaThread getThreadFilter(IJavaDebugTarget target) {
		return fFilteredThreadsByTarget.get(target);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getThreadFilters()
	 */
	@Override
	public IJavaThread[] getThreadFilters() {
		IJavaThread[] threads = null;
		Collection<IJavaThread> values = fFilteredThreadsByTarget.values();
		threads = new IJavaThread[values.size()];
		values.toArray(threads);
		return threads;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaBreakpoint#removeThreadFilter(org.eclipse
	 * .jdt.debug.core.IJavaDebugTarget)
	 */
	@Override
	public void removeThreadFilter(IJavaDebugTarget javaTarget)
			throws CoreException {
		if (!(javaTarget instanceof JDIDebugTarget)) {
			return;
		}
		JDIDebugTarget target = (JDIDebugTarget) javaTarget;
		if (fFilteredThreadsByTarget.remove(target) != null) {
			recreate(target);
			fireChanged();
		}
	}

	/**
	 * Returns whether this breakpoint should be installed in the given
	 * reference type in the given target according to registered breakpoint
	 * listeners.
	 *
	 * @param target
	 *            debug target
	 * @param type
	 *            reference type or <code>null</code> if this breakpoint is not
	 *            installed in a specific type
	 */
	protected boolean queryInstallListeners(JDIDebugTarget target,
			ReferenceType type) {
		JDIDebugPlugin plugin = JDIDebugPlugin.getDefault();
		if (plugin != null) {
			IJavaType jt = null;
			if (type != null) {
				jt = JDIType.createType(target, type);
			}
			return plugin.fireInstalling(target, this, jt);
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaBreakpoint#addInstanceFilter(org.eclipse
	 * .jdt.debug.core.IJavaObject)
	 */
	@Override
	public void addInstanceFilter(IJavaObject object) throws CoreException {
		if (fInstanceFilters == null) {
			fInstanceFilters = new ArrayList<>();
		}
		if (!fInstanceFilters.contains(object)) {
			fInstanceFilters.add(object);
			recreate((JDIDebugTarget) object.getDebugTarget());
			fireChanged();
		}
	}

	/**
	 * Change notification when there are no marker changes. If the marker does
	 * not exist, do not fire a change notification (the marker may not exist if
	 * the associated project was closed).
	 */
	protected void fireChanged() {
		DebugPlugin plugin = DebugPlugin.getDefault();
		if (plugin != null && markerExists()) {
			plugin.getBreakpointManager().fireBreakpointChanged(this);
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getInstanceFilters()
	 */
	@Override
	public IJavaObject[] getInstanceFilters() {
		if (fInstanceFilters == null || fInstanceFilters.isEmpty()) {
			return fgEmptyInstanceFilters;
		}
		return fInstanceFilters
				.toArray(new IJavaObject[fInstanceFilters.size()]);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaBreakpoint#removeInstanceFilter(org.eclipse
	 * .jdt.debug.core.IJavaObject)
	 */
	@Override
	public void removeInstanceFilter(IJavaObject object) throws CoreException {
		if (fInstanceFilters == null) {
			return;
		}
		if (fInstanceFilters.remove(object)) {
			recreate((JDIDebugTarget) object.getDebugTarget());
			fireChanged();
		}
	}

	/**
	 * An attribute of this breakpoint has changed - recreate event requests in
	 * all targets.
	 */
	protected void recreate() throws CoreException {
		DebugPlugin plugin = DebugPlugin.getDefault();
		if (plugin != null) {
			IDebugTarget[] targets = plugin.getLaunchManager()
					.getDebugTargets();
			for (IDebugTarget target : targets) {
				MultiStatus multiStatus = new MultiStatus(
						JDIDebugPlugin.getUniqueIdentifier(),
						JDIDebugPlugin.ERROR,
						JDIDebugBreakpointMessages.JavaBreakpoint_Exception,
						null);
				IJavaDebugTarget jdiTarget = target
						.getAdapter(IJavaDebugTarget.class);
				if (jdiTarget instanceof JDIDebugTarget) {
					try {
						recreate((JDIDebugTarget) jdiTarget);
					} catch (CoreException e) {
						multiStatus.add(e.getStatus());
					}
				}
				if (!multiStatus.isOK()) {
					throw new CoreException(multiStatus);
				}
			}
		}
	}

	/**
	 * Recreate this breakpoint in the given target, as long as the target
	 * already contains this breakpoint.
	 *
	 * @param target
	 *            the target in which to re-create the breakpoint
	 */
	protected void recreate(JDIDebugTarget target) throws CoreException {
		if (target.isAvailable() && target.getBreakpoints().contains(this)) {
			removeRequests(target);
			createRequests(target);
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.debug.core.model.Breakpoint#setEnabled(boolean)
	 */
	@Override
	public void setEnabled(boolean enabled) throws CoreException {
		super.setEnabled(enabled);
		recreate();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsInstanceFilters()
	 */
	@Override
	public boolean supportsInstanceFilters() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#supportsThreadFilters()
	 */
	@Override
	public boolean supportsThreadFilters() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaBreakpoint#addBreakpointListener(java
	 * .lang.String)
	 */
	@Override
	public synchronized void addBreakpointListener(String identifier)
			throws CoreException {
		if (fBreakpointListenerIds == null) {
			fBreakpointListenerIds = new ArrayList<>();
		}
		if (!fBreakpointListenerIds.contains(identifier)) {
			fBreakpointListenerIds.add(identifier);
			writeBreakpointListeners();
		}
	}

	/**
	 * Writes the current breakpoint listener collection to the underlying
	 * marker.
	 *
	 * @throws CoreException
	 */
	private void writeBreakpointListeners() throws CoreException {
		StringBuffer buf = new StringBuffer();
		Iterator<String> iterator = fBreakpointListenerIds.iterator();
		while (iterator.hasNext()) {
			buf.append(iterator.next());
			if (iterator.hasNext()) {
				buf.append(","); //$NON-NLS-1$
			}
		}
		setAttribute(BREAKPOINT_LISTENERS, buf.toString());
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaBreakpoint#removeBreakpointListener(java
	 * .lang.String)
	 */
	@Override
	public synchronized boolean removeBreakpointListener(String identifier)
			throws CoreException {
		if (fBreakpointListenerIds != null) {
			if (fBreakpointListenerIds.remove(identifier)) {
				writeBreakpointListeners();
				return true;
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpoint#getBreakpointListeners()
	 */
	@Override
	public synchronized String[] getBreakpointListeners() throws CoreException {
		// use the cache in case the underlying marker has been deleted
		if (fBreakpointListenerIds == null) {
			return new String[0];
		}
		return fBreakpointListenerIds
				.toArray(new String[fBreakpointListenerIds.size()]);
	}

	/**
	 * Reads breakpoint listeners from the underlying marker.
	 *
	 * @return breakpoint listener identifiers stored in this breakpoint's
	 *         marker
	 * @throws CoreException
	 *             if no marker
	 */
	private String[] readBreakpointListeners() throws CoreException {
		String value = ensureMarker().getAttribute(BREAKPOINT_LISTENERS,
				(String) null);
		if (value == null) {
			return new String[0];
		}
		return value.split(","); //$NON-NLS-1$
	}
}
