/*******************************************************************************
 * Copyright (c) 2000, 2017 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.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$

	/**
	 * 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,
					null);
			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();
	}

	/**
	 * @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);
		StringBuffer buffer = new StringBuffer();
		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;
	}
}
