/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.core.breakpoints;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
import org.eclipse.jdt.debug.core.IJavaObject;
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.JDIThread;
import org.eclipse.jdt.internal.debug.core.model.JDIValue;
import org.eclipse.jdt.internal.debug.core.model.MethodResult;
import org.eclipse.jdt.internal.debug.core.model.MethodResult.ResultType;

import com.sun.jdi.ClassType;
import com.sun.jdi.Location;
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.Event;
import com.sun.jdi.event.ExceptionEvent;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.ExceptionRequest;

public class JavaExceptionBreakpoint extends JavaBreakpoint implements
		IJavaExceptionBreakpoint {

	public static final String JAVA_EXCEPTION_BREAKPOINT = "org.eclipse.jdt.debug.javaExceptionBreakpointMarker"; //$NON-NLS-1$

	/**
	 * Exception breakpoint attribute storing the suspend on caught value (value
	 * <code>"org.eclipse.jdt.debug.core.caught"</code>). This attribute is
	 * stored as a <code>boolean</code>. When this attribute is
	 * <code>true</code>, a caught exception of the associated type will cause
	 * execution to suspend .
	 */
	protected static final String CAUGHT = "org.eclipse.jdt.debug.core.caught"; //$NON-NLS-1$
	/**
	 * Exception breakpoint attribute storing the suspend on uncaught value
	 * (value <code>"org.eclipse.jdt.debug.core.uncaught"</code>). This
	 * attribute is stored as a <code>boolean</code>. When this attribute is
	 * <code>true</code>, an uncaught exception of the associated type will
	 * cause execution to suspend.
	 */
	protected static final String UNCAUGHT = "org.eclipse.jdt.debug.core.uncaught"; //$NON-NLS-1$
	/**
	 * Exception breakpoint attribute storing the checked value (value
	 * <code>"org.eclipse.jdt.debug.core.checked"</code>). This attribute is
	 * stored as a <code>boolean</code>, indicating whether an exception is a
	 * checked exception.
	 */
	protected static final String CHECKED = "org.eclipse.jdt.debug.core.checked"; //$NON-NLS-1$

	/**
	 * Exception breakpoint attribute storing the String value (value
	 * <code>"org.eclipse.jdt.debug.core.filters"</code>). This attribute is
	 * stored as a <code>String</code>, a comma delimited list of class filters.
	 * The filters are applied as inclusion or exclusion depending on
	 * INCLUSIVE_FILTERS.
	 */
	protected static final String INCLUSION_FILTERS = "org.eclipse.jdt.debug.core.inclusion_filters"; //$NON-NLS-1$

	/**
	 * Exception breakpoint attribute storing the String value (value
	 * <code>"org.eclipse.jdt.debug.core.filters"</code>). This attribute is
	 * stored as a <code>String</code>, a comma delimited list of class filters.
	 * The filters are applied as inclusion or exclusion depending on
	 * INCLUSIVE_FILTERS.
	 */
	protected static final String EXCLUSION_FILTERS = "org.eclipse.jdt.debug.core.exclusion_filters"; //$NON-NLS-1$
	/**
	 * Allows the user to specify whether we should suspend if subclasses of the
	 * specified exception are thrown/caught
	 *
	 * @since 3.2
	 */
	protected static final String SUSPEND_ON_SUBCLASSES = "org.eclipse.jdt.debug.core.suspend_on_subclasses"; //$NON-NLS-1$

	/**
	 * Allows the user to specify that each exception instance matching this breakpoint should suspend only once, i.e., re-throws and finally clauses
	 * will not again suspend on an exception instance that had already caused a suspend.
	 *
	 * @since 3.14
	 */
	protected static final String SUSPEND_ON_RECURRENCE = "org.eclipse.jdt.debug.core.suspend_on_recurrence"; //$NON-NLS-1$

	/**
	 * Name of the exception that was actually hit (could be a sub-type of the
	 * type that is being caught).
	 */
	protected String fExceptionName = null;

	/**
	 * The current set of inclusion class filters.
	 */
	protected String[] fInclusionClassFilters = null;

	/**
	 * The current set of inclusion class filters.
	 */
	protected String[] fExclusionClassFilters = null;

	private ObjectReference fLastException;
	private JDIDebugTarget fLastTarget;

	public JavaExceptionBreakpoint() {
	}

	/**
	 * Creates and returns an exception breakpoint for the given (throwable)
	 * type. Caught and uncaught specify where the exception should cause thread
	 * suspensions - that is, in caught and/or uncaught locations. Checked
	 * indicates if the given exception is a checked exception.
	 *
	 * @param resource
	 *            the resource on which to create the associated breakpoint
	 *            marker
	 * @param exceptionName
	 *            the fully qualified name of the exception for which to create
	 *            the breakpoint
	 * @param caught
	 *            whether to suspend in caught locations
	 * @param uncaught
	 *            whether to suspend in uncaught locations
	 * @param checked
	 *            whether the exception is a checked exception
	 * @param add
	 *            whether to add this breakpoint to the breakpoint manager
	 * @return a Java exception breakpoint
	 * @exception DebugException
	 *                if unable to create the associated marker due to a lower
	 *                level exception.
	 */
	public JavaExceptionBreakpoint(final IResource resource,
			final String exceptionName, final boolean caught,
			final boolean uncaught, final boolean checked, final boolean add,
			final Map<String, Object> attributes) throws DebugException {
		IWorkspaceRunnable wr = new IWorkspaceRunnable() {

			@Override
			public void run(IProgressMonitor monitor) throws CoreException {
				// create the marker
				setMarker(resource.createMarker(JAVA_EXCEPTION_BREAKPOINT));

				// add attributes
				attributes.put(IBreakpoint.ID, getModelIdentifier());
				attributes.put(TYPE_NAME, exceptionName);
				attributes.put(ENABLED, Boolean.TRUE);
				attributes.put(CAUGHT, Boolean.valueOf(caught));
				attributes.put(UNCAUGHT, Boolean.valueOf(uncaught));
				attributes.put(CHECKED, Boolean.valueOf(checked));
				attributes.put(SUSPEND_POLICY, new Integer(
						getDefaultSuspendPolicy()));

				ensureMarker().setAttributes(attributes);

				register(add);
			}

		};
		run(getMarkerRule(resource), wr);
	}

	/**
	 * Creates a request in the given target to suspend when the given exception
	 * type is thrown. The request is returned installed, configured, and
	 * enabled as appropriate for this breakpoint.
	 */
	@Override
	protected EventRequest[] newRequests(JDIDebugTarget target,
			ReferenceType type) throws CoreException {
		if (!isCaught() && !isUncaught()) {
			return null;
		}
		ExceptionRequest request = null;
		EventRequestManager manager = target.getEventRequestManager();
		if (manager == null) {
			target.requestFailed(
					JDIDebugBreakpointMessages.JavaExceptionBreakpoint_Unable_to_create_breakpoint_request___VM_disconnected__1,
					new VMDisconnectedException());
			return null;
		}

		try {
			request = manager.createExceptionRequest(type, isCaught(),
					isUncaught());
			configureRequest(request, target);
		} catch (VMDisconnectedException e) {
			if (target.isAvailable()) {
				JDIDebugPlugin.log(e);
			}
			return null;
		} catch (RuntimeException e) {
			target.internalError(e);
			return null;
		}
		return new EventRequest[] { request };
	}

	/**
	 * Enable this exception breakpoint.
	 *
	 * If the exception breakpoint is not catching caught or uncaught, turn both
	 * modes on. If this isn't done, the resulting state (enabled with caught
	 * and uncaught both disabled) is ambiguous.
	 */
	@Override
	public void setEnabled(boolean enabled) throws CoreException {
		if (enabled) {
			if (!(isCaught() || isUncaught())) {
				setAttributes(new String[] { CAUGHT, UNCAUGHT }, new Object[] {
						Boolean.TRUE, Boolean.TRUE });
			}
		}
		super.setEnabled(enabled);
	}

	/**
	 * Sets the values for whether this breakpoint will suspend execution when
	 * the associated exception is thrown and caught or not caught.
	 */
	protected void setCaughtAndUncaught(boolean caught, boolean uncaught)
			throws CoreException {
		Object[] values = new Object[] { Boolean.valueOf(caught),
				Boolean.valueOf(uncaught) };
		String[] attributes = new String[] { CAUGHT, UNCAUGHT };
		setAttributes(attributes, values);
	}

	/**
	 * @see IJavaExceptionBreakpoint#isCaught()
	 */
	@Override
	public boolean isCaught() throws CoreException {
		return ensureMarker().getAttribute(CAUGHT, false);
	}

	/**
	 * @see IJavaExceptionBreakpoint#setCaught(boolean)
	 */
	@Override
	public void setCaught(boolean caught) throws CoreException {
		if (caught == isCaught()) {
			return;
		}
		setAttribute(CAUGHT, caught);
		if (caught && !isEnabled()) {
			setEnabled(true);
		} else if (!(caught || isUncaught())) {
			setEnabled(false);
		}
		recreate();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint#setSuspendOnSubclasses
	 * (boolean)
	 */
	public void setSuspendOnSubclasses(boolean suspend) throws CoreException {
		if (suspend != isSuspendOnSubclasses()) {
			setAttribute(SUSPEND_ON_SUBCLASSES, suspend);
			recreate();
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint#isSuspendOnSubclasses
	 * ()
	 */
	public boolean isSuspendOnSubclasses() throws CoreException {
		return ensureMarker().getAttribute(SUSPEND_ON_SUBCLASSES, false);
	}

	/**
	 * @see IJavaExceptionBreakpoint#isUncaught()
	 */
	@Override
	public boolean isUncaught() throws CoreException {
		return ensureMarker().getAttribute(UNCAUGHT, false);
	}

	/**
	 * @see IJavaExceptionBreakpoint#setUncaught(boolean)
	 */
	@Override
	public void setUncaught(boolean uncaught) throws CoreException {
		if (uncaught == isUncaught()) {
			return;
		}
		setAttribute(UNCAUGHT, uncaught);
		if (uncaught && !isEnabled()) {
			setEnabled(true);
		} else if (!(uncaught || isCaught())) {
			setEnabled(false);
		}
		recreate();
	}

	@Override
	public SuspendOnRecurrenceStrategy getSuspendOnRecurrenceStrategy() throws CoreException {
		int valueIndex = ensureMarker().getAttribute(SUSPEND_ON_RECURRENCE, SuspendOnRecurrenceStrategy.RECURRENCE_UNCONFIGURED.ordinal());
		return SuspendOnRecurrenceStrategy.values()[valueIndex];
	}

	@Override
	public void setSuspendOnRecurrenceStrategy(SuspendOnRecurrenceStrategy strategy) throws CoreException {
		if (strategy == getSuspendOnRecurrenceStrategy()) {
			return;
		}
		setAttribute(SUSPEND_ON_RECURRENCE, strategy.ordinal());
		// don't re-create, the change only affects the debugger, not the target
	}

	/**
	 * @see IJavaExceptionBreakpoint#isChecked()
	 */
	@Override
	public boolean isChecked() throws CoreException {
		return ensureMarker().getAttribute(CHECKED, false);
	}

	/**
	 * @see JavaBreakpoint#setRequestThreadFilter(EventRequest)
	 */
	@Override
	protected void setRequestThreadFilter(EventRequest request,
			ThreadReference thread) {
		((ExceptionRequest) request).addThreadFilter(thread);
	}

	/**
	 * @see JavaBreakpoint#handleBreakpointEvent(Event, JDIDebugTarget,
	 *      JDIThread) Decides how to handle an exception being thrown
	 *
	 * @return true if we do not want to suspend false otherwise
	 */
	@Override
	public boolean handleBreakpointEvent(Event event, JDIThread thread,
			boolean suspendVote) {
		boolean result = handleBreakpointEventInternal(event, thread, suspendVote);
		if (!result) {
			if (event instanceof ExceptionEvent) {
				// about to suspend, store result
				ExceptionEvent exceptionEvent = (ExceptionEvent) event;
				thread.setMethodResult(new MethodResult(exceptionEvent.location().method(), -1, exceptionEvent.exception(), ResultType.throwing));
			}
		}
		return result;
	}

	private boolean handleBreakpointEventInternal(Event event, JDIThread thread, boolean suspendVote) {
		if (event instanceof ExceptionEvent) {
			ObjectReference ex = ((ExceptionEvent) event).exception();
			fLastTarget = thread.getJavaDebugTarget();
			fLastException = ex;
			String name = null;
			try {
				name = ex.type().name();
				if (!name.equals(getTypeName())) {
					if (!isSuspendOnSubclasses()
							& isSubclass((ClassType) ex.type(), getTypeName())) {
						return true;
					}
				}
			} catch (VMDisconnectedException e) {
				return true;
			} catch (CoreException e) {
				JDIDebugPlugin.log(e);
			} catch (RuntimeException e) {
				try {
					thread.targetRequestFailed(e.getMessage(), e);
				} catch (DebugException de) {
					JDIDebugPlugin.log(e);
					return false;
				}
			}
			setExceptionName(name);
			disableTriggerPoint(event);
			IBreakpoint[] allBreakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints();
			for (IBreakpoint iBreakpoint : allBreakpoints) {
				if (iBreakpoint instanceof JavaExceptionBreakpoint) {
					JavaExceptionBreakpoint jExceptionBreakpoint = (JavaExceptionBreakpoint)iBreakpoint;
					try {
						//This Java Exception breakpoint is the  breakpoint created for catching compilation and Uncaught exception in JavaDebugOptionsManagaer initialization
						// This does not have scope defined
						if (jExceptionBreakpoint.getTypeName().equals(name)) {
							if (jExceptionBreakpoint.getExclusionClassFilters().length >= 1
						|| jExceptionBreakpoint.getInclusionClassFilters().length >= 1
						|| filtersIncludeDefaultPackage(jExceptionBreakpoint.fInclusionClassFilters)
						|| filtersIncludeDefaultPackage(jExceptionBreakpoint.fExclusionClassFilters)) {
							Location location = ((ExceptionEvent) event).location();
							String typeName = location.declaringType().name();
							boolean defaultPackage = typeName.indexOf('.') == -1;
							boolean included = true;
							String[] filters = jExceptionBreakpoint.getInclusionClassFilters();
							if (filters.length > 0) {
								included = matchesFilters(filters, typeName, defaultPackage);
							}
							boolean excluded = false;
							filters = jExceptionBreakpoint.getExclusionClassFilters();
							if (filters.length > 0) {
								excluded = matchesFilters(filters, typeName, defaultPackage);
							}
							if (included && !excluded) {
								return !suspend(thread, suspendVote);
							}
							return true;
							}
						}
					}
					catch (CoreException e) {
						e.printStackTrace();
					}
				}
			}

			return !suspend(thread, suspendVote);
		}
		return true;
	}

	/**
	 * Returns whether the given class type is a subclass of the classes with the
	 * given name.
	 *
	 * @param type
	 *            the class type reference
	 * @return true if the specified the class type is a subclass of the class
	 *         with the given name
	 * @since 3.2
	 */
	private boolean isSubclass(ClassType type, String typeName) {
		type = type.superclass();
		while (type != null) {
			if (type.name().equals(typeName)) {
				return true;
			}
			type = type.superclass();
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#setInstalledIn
	 * (org.eclipse.jdt.debug.core.IJavaDebugTarget, boolean)
	 */
	@Override
	protected void setInstalledIn(IJavaDebugTarget target, boolean installed) {
		fLastException = null;
		fLastTarget = null;
		super.setInstalledIn(target, installed);
	}

	/**
	 * Determines of the filters for this exception include the default package
	 * or not
	 *
	 * @param filters
	 *            the list of filters to inspect
	 * @return true if any one of the specified filters include the default
	 *         package
	 */
	protected boolean filtersIncludeDefaultPackage(String[] filters) {
		for (String filter : filters) {
			if (filter.length() == 0 || (filter.indexOf('.') == -1)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns whether the given type is in the given filter set.
	 *
	 * @param filters
	 *            the filter set
	 * @param typeName
	 *            fully qualified type name
	 * @param defaultPackage
	 *            whether the type name is in the default package
	 * @return boolean
	 */
	protected boolean matchesFilters(String[] filters, String typeName,
			boolean defaultPackage) {
		for (String filter2 : filters) {
			String filter = filter2;
			if (defaultPackage && filter.length() == 0) {
				return true;
			}

			filter = filter.replaceAll("\\.", "\\\\."); //$NON-NLS-1$//$NON-NLS-2$
			filter = filter.replaceAll("\\*", "\\.\\*"); //$NON-NLS-1$//$NON-NLS-2$
			Pattern pattern = Pattern.compile(filter);
			if (pattern.matcher(typeName).find()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Sets the name of the exception that was last hit
	 *
	 * @param name
	 *            fully qualified exception name
	 */
	protected void setExceptionName(String name) {
		fExceptionName = name;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint#getExceptionTypeName
	 * ()
	 */
	@Override
	public String getExceptionTypeName() {
		return fExceptionName;
	}

	/**
	 * @see IJavaExceptionBreakpoint#getFilters()
	 * @deprecated
	 */
	@Override
	@Deprecated
	public String[] getFilters() {
		String[] iFilters = getInclusionFilters();
		String[] eFilters = getExclusionFilters();
		String[] filters = new String[iFilters.length + eFilters.length];
		System.arraycopy(iFilters, 0, filters, 0, iFilters.length);
		System.arraycopy(eFilters, 0, filters, iFilters.length, eFilters.length);
		return filters;
	}

	/**
	 * @see IJavaExceptionBreakpoint#setFilters(String[], boolean)
	 * @deprecated
	 */
	@Override
	@Deprecated
	public void setFilters(String[] filters, boolean inclusive)
			throws CoreException {
		if (inclusive) {
			setInclusionFilters(filters);
		} else {
			setExclusionFilters(filters);
		}
		recreate();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#
	 * configureRequest(com.sun.jdi.request.EventRequest,
	 * org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
	 */
	@Override
	protected void configureRequest(EventRequest eRequest, JDIDebugTarget target)
			throws CoreException {
		String[] iFilters = getInclusionClassFilters();
		String[] eFilters = getExclusionClassFilters();

		ExceptionRequest request = (ExceptionRequest) eRequest;

		if (iFilters.length == 1) {
			if (eFilters.length == 0) {
				request.addClassFilter(iFilters[0]);
			}
		} else if (eFilters.length == 1) {
			if (iFilters.length == 0) {
				request.addClassExclusionFilter(eFilters[0]);
			}
		}

		super.configureRequest(eRequest, target);
	}

	/**
	 * Serializes the array of Strings into one comma separated String. Removes
	 * duplicates.
	 */
	protected String serializeList(String[] list) {
		if (list == null) {
			return ""; //$NON-NLS-1$
		}
		Set<String> set = new HashSet<>(list.length);
		StringBuilder buffer = new StringBuilder();
		for (int i = 0; i < list.length; i++) {
			if (i > 0 && i < list.length) {
				buffer.append(',');
			}
			String pattern = list[i];
			if (!set.contains(pattern)) {
				if (pattern.length() == 0) {
					// serialize the default package
					pattern = "."; //$NON-NLS-1$
				}
				buffer.append(pattern);
				set.add(pattern);
			}
		}
		return buffer.toString();
	}

	/**
	 * Parses the comma separated String into an array of Strings
	 */
	protected String[] parseList(String listString) {
		List<String> list = new ArrayList<>(10);
		StringTokenizer tokenizer = new StringTokenizer(listString, ","); //$NON-NLS-1$
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			if (token.equals(".")) { //$NON-NLS-1$
				// serialized form for the default package
				// @see serializeList(String[])
				token = ""; //$NON-NLS-1$
			}
			list.add(token);
		}
		return list.toArray(new String[list.size()]);
	}

	/**
	 * @see IJavaExceptionBreakpoint#isInclusiveFiltered()
	 * @deprecated
	 */
	@Override
	@Deprecated
	public boolean isInclusiveFiltered() throws CoreException {
		return ensureMarker().getAttribute(INCLUSION_FILTERS, "").length() > 0; //$NON-NLS-1$
	}

	protected String[] getInclusionClassFilters() {
		if (fInclusionClassFilters == null) {
			try {
				fInclusionClassFilters = parseList(ensureMarker().getAttribute(
						INCLUSION_FILTERS, "")); //$NON-NLS-1$
			} catch (CoreException ce) {
				fInclusionClassFilters = new String[] {};
			}
		}
		return fInclusionClassFilters;
	}

	protected void setInclusionClassFilters(String[] filters) {
		fInclusionClassFilters = filters;
	}

	protected String[] getExclusionClassFilters() {
		if (fExclusionClassFilters == null) {
			try {
				fExclusionClassFilters = parseList(ensureMarker().getAttribute(
						EXCLUSION_FILTERS, "")); //$NON-NLS-1$
			} catch (CoreException ce) {
				fExclusionClassFilters = new String[] {};
			}
		}
		return fExclusionClassFilters;
	}

	protected void setExclusionClassFilters(String[] filters) {
		fExclusionClassFilters = filters;
	}

	/**
	 * @see JavaBreakpoint#installableReferenceType(ReferenceType,
	 *      JDIDebugTarget)
	 */
	@Override
	protected boolean installableReferenceType(ReferenceType type,
			JDIDebugTarget target) throws CoreException {
		String installableType = getTypeName();
		String queriedType = type.name();
		if (installableType == null || queriedType == null) {
			return false;
		}
		if (installableType.equals(queriedType)) {
			return queryInstallListeners(target, type);
		}

		return false;
	}

	/**
	 * @see org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint#getExclusionFilters()
	 */
	@Override
	public String[] getExclusionFilters() {
		return getExclusionClassFilters();
	}

	/**
	 * @see org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint#getInclusionFilters()
	 */
	@Override
	public String[] getInclusionFilters() {
		return getInclusionClassFilters();
	}

	/**
	 * @see org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint#setExclusionFilters(String[])
	 */
	@Override
	public void setExclusionFilters(String[] filters) throws CoreException {
		String serializedFilters = serializeList(filters);

		if (serializedFilters.equals(ensureMarker().getAttribute(
				EXCLUSION_FILTERS, ""))) { //$NON-NLS-1$
			// no change
			return;
		}

		setExclusionClassFilters(filters);

		setAttribute(EXCLUSION_FILTERS, serializedFilters);
		recreate();
	}

	/**
	 * @see org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint#setInclusionFilters(String[])
	 */
	@Override
	public void setInclusionFilters(String[] filters) throws CoreException {
		String serializedFilters = serializeList(filters);

		if (serializedFilters.equals(ensureMarker().getAttribute(
				INCLUSION_FILTERS, ""))) { //$NON-NLS-1$
			// no change
			return;
		}

		setInclusionClassFilters(filters);

		setAttribute(INCLUSION_FILTERS, serializedFilters);
		recreate();
	}

	/**
	 * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#addInstanceFilter(EventRequest,
	 *      ObjectReference)
	 */
	@Override
	protected void addInstanceFilter(EventRequest request,
			ObjectReference object) {
		if (request instanceof ExceptionRequest) {
			((ExceptionRequest) request).addInstanceFilter(object);
		}
	}

	/**
	 * Returns the last exception object that was encountered by this exception
	 *
	 * TODO: make API in future release.
	 *
	 * @return
	 */
	public IJavaObject getLastException() {
		if (fLastException != null) {
			return (IJavaObject) JDIValue.createValue(fLastTarget,
					fLastException);
		}
		return null;
	}
}
