/*******************************************************************************
 * Copyright (c) 2000, 2015 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;

import org.eclipse.core.resources.ISaveContext;
import org.eclipse.core.resources.ISaveParticipant;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jdi.Bootstrap;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.dom.Message;
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.IJavaHotCodeReplaceListener;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
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.debug.eval.IAstEvaluationEngine;
import org.eclipse.jdt.internal.debug.core.breakpoints.BreakpointListenerManager;
import org.eclipse.jdt.internal.debug.core.hcr.JavaHotCodeReplaceManager;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;

import com.sun.jdi.VirtualMachineManager;

/**
 * The plug-in class for the JDI Debug Model plug-in.
 */
public class JDIDebugPlugin extends Plugin implements IEclipsePreferences.IPreferenceChangeListener {

	/**
	 * Boolean preference controlling if hot code replace is enabled.
	 *
	 * @since 3.11
	 */
	public static final String PREF_ENABLE_HCR = JDIDebugPlugin
			.getUniqueIdentifier() + ".enable_hcr"; //$NON-NLS-1$

	/**
	 * integer preference controlling if we should, by default, suspend the VM
	 * instead of the thread
	 *
	 * @since 3.2
	 */
	public static final String PREF_DEFAULT_BREAKPOINT_SUSPEND_POLICY = JDIDebugPlugin
			.getUniqueIdentifier() + ".default_breakpoint_suspend_policy"; //$NON-NLS-1$

	/**
	 * integer preference controlling which default suspend option to set on new
	 * watchpoints
	 *
	 * @since 3.3.1
	 */
	public static final String PREF_DEFAULT_WATCHPOINT_SUSPEND_POLICY = JDIDebugPlugin
			.getUniqueIdentifier() + "default_watchpoint_suspend_policy"; //$NON-NLS-1$

	/**
	 * Boolean preference controlling if references should be displayed as
	 * variables in the variables and expressions view
	 *
	 * @since 3.3
	 */
	public static final String PREF_SHOW_REFERENCES_IN_VAR_VIEW = JDIDebugPlugin
			.getUniqueIdentifier() + ".show_references_in_var_view"; //$NON-NLS-1$

	/**
	 * Integer preference determining the maximum number of references that
	 * should be returned to the user when displaying reference information
	 *
	 * @since 3.3
	 */
	public static final String PREF_ALL_REFERENCES_MAX_COUNT = JDIDebugPlugin
			.getUniqueIdentifier() + "._all_references_max_count"; //$NON-NLS-1$

	/**
	 * Integer preference determining the maximum number of instances that
	 * should be returned to the user when displaying instance information
	 *
	 * @since 3.3
	 */
	public static final String PREF_ALL_INSTANCES_MAX_COUNT = JDIDebugPlugin
			.getUniqueIdentifier() + ".all_instances_max_count"; //$NON-NLS-1$

	/**
	 * Boolean preference controlling if advanced sourcelookup is enabled.
	 * 
	 * @since 3.11
	 */
	public static final String PREF_ENABLE_ADVANCED_SOURCELOOKUP = JDIDebugPlugin
			.getUniqueIdentifier() + ".enable_advanced_sourcelookup"; //$NON-NLS-1$

	/**
	 * Extension point for java logical structures.
	 *
	 * @since 3.1
	 */
	public static final String EXTENSION_POINT_JAVA_LOGICAL_STRUCTURES = "javaLogicalStructures"; //$NON-NLS-1$

	/**
	 * Extension point for java breakpoint action delegates.
	 *
	 * @since 3.5
	 */
	public static final String EXTENSION_POINT_JAVA_BREAKPOINT_LISTENERS = "breakpointListeners"; //$NON-NLS-1$

	/**
	 * Status code indicating an unexpected error.
	 */
	public static final int ERROR = 120;

	/**
	 * Status code indicating an unexpected internal error. Internal errors
	 * should never be displayed to the user in dialogs or status text. Internal
	 * error messages are not translated.
	 */
	public static final int INTERNAL_ERROR = 125;

	private static JDIDebugPlugin fgPlugin;

	/**
	 * Breakpoint listener list.
	 */
	private ListenerList<IJavaBreakpointListener> fBreakpointListeners = null;

	/**
	 * Breakpoint notification types
	 */
	private static final int ADDING = 1;
	private static final int INSTALLED = 2;
	private static final int REMOVED = 3;
	private static final int COMPILATION_ERRORS = 4;
	private static final int RUNTIME_EXCEPTION = 5;

	/**
	 * Whether this plug-in is in trace mode. Extra messages are logged in trace
	 * mode.
	 */
	private boolean fTrace = false;

	/**
	 * Detected (speculated) JDI interface version
	 */
	private static int[] fJDIVersion = null;

	/**
	 * Status code used by the debug model to retrieve a thread to use for
	 * evaluations, via a status handler. A status handler is contributed by the
	 * Java debug UI. When not present, the debug model uses any suspended
	 * thread.
	 *
	 * @since 3.0
	 */
	public static final int INFO_EVALUATION_THREAD = 110;

	/**
	 * Associated status to retrieve a thread.
	 */
	public static final IStatus STATUS_GET_EVALUATION_THREAD = new Status(
			IStatus.INFO, getUniqueIdentifier(), INFO_EVALUATION_THREAD,
			"Provides thread context for an evaluation", null); //$NON-NLS-1$

	/**
	 * Status code used by the debug model to retrieve a frame to use for
	 * evaluations, via a status handler. A status handler is contributed by the
	 * Java debug UI. When not present, the debug model uses any suspended
	 * thread.
	 *
	 * @since 3.0
	 */
	public static final int INFO_EVALUATION_STACK_FRAME = 111;

	/**
	 * Associated status to retrieve a stack frame.
	 */
	public static IStatus STATUS_GET_EVALUATION_FRAME = new Status(
			IStatus.INFO, getUniqueIdentifier(), INFO_EVALUATION_STACK_FRAME,
			"Provides thread context for an evaluation", null); //$NON-NLS-1$

	/**
	 * Manages breakpoint listener extensions
	 */
	private BreakpointListenerManager fJavaBreakpointManager;

	/**
	 * Returns whether the debug UI plug-in is in trace mode.
	 *
	 * @return whether the debug UI plug-in is in trace mode
	 */
	public boolean isTraceMode() {
		return fTrace;
	}

	/**
	 * Logs the given message if in trace mode.
	 *
	 * @param message the string to log
	 */
	public static void logTraceMessage(String message) {
		if (getDefault().isTraceMode()) {
			IStatus s = new Status(IStatus.WARNING,
					JDIDebugPlugin.getUniqueIdentifier(), INTERNAL_ERROR,
					message, null);
			getDefault().getLog().log(s);
		}
	}

	/**
	 * Return the singleton instance of the JDI Debug Model plug-in.
	 *
	 * @return the singleton instance of JDIDebugPlugin
	 */
	public static JDIDebugPlugin getDefault() {
		return fgPlugin;
	}

	/**
	 * Convenience method which returns the unique identifier of this plug-in.
	 * <br><br>
	 * Value is: <code>org.eclipse.jdt.debug</code>
	 * @return the unique id of the JDT debug core plug-in
	 */
	public static String getUniqueIdentifier() {
		return "org.eclipse.jdt.debug"; //$NON-NLS-1$
	}

	/**
	 * Returns the detected version of JDI support. This is intended to
	 * distinguish between clients that support JDI 1.4 methods like hot code
	 * replace.
	 *
	 * @return an array of version numbers, major followed by minor
	 * @since 2.1
	 */
	public static int[] getJDIVersion() {
		if (fJDIVersion == null) {
			fJDIVersion = new int[2];
			VirtualMachineManager mgr = Bootstrap.virtualMachineManager();
			fJDIVersion[0] = mgr.majorInterfaceVersion();
			fJDIVersion[1] = mgr.minorInterfaceVersion();
		}
		return fJDIVersion;
	}

	/**
	 * Returns if the JDI version being used is greater than or equal to the
	 * given version (major, minor).
	 *
	 * @param version the array of version number identifiers to compare
	 * @return boolean
	 */
	public static boolean isJdiVersionGreaterThanOrEqual(int[] version) {
		int[] runningVersion = getJDIVersion();
		return runningVersion[0] > version[0] || (runningVersion[0] == version[0] && runningVersion[1] >= version[1]);
	}

	public JDIDebugPlugin() {
		super();
		fgPlugin = this;
	}

	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);
		new JDIDebugOptions(context);
		ResourcesPlugin.getWorkspace().addSaveParticipant(getUniqueIdentifier(),
				new ISaveParticipant() {
					@Override
					public void doneSaving(ISaveContext c) {
					}

					@Override
					public void prepareToSave(ISaveContext c)
							throws CoreException {
					}

					@Override
					public void rollback(ISaveContext c) {
					}

					@Override
					public void saving(ISaveContext c) throws CoreException {
						IEclipsePreferences node = InstanceScope.INSTANCE.getNode(getUniqueIdentifier());
						if(node != null) {
							try {
								node.flush();
							} catch (BackingStoreException bse) {
								log(bse);
							}
						}
					}
				});
		JavaHotCodeReplaceManager.getDefault().startup();
		fBreakpointListeners = new ListenerList<>();
		fJavaBreakpointManager = new BreakpointListenerManager();
		IEclipsePreferences node = InstanceScope.INSTANCE.getNode(getUniqueIdentifier());
		if(node != null) {
			node.addPreferenceChangeListener(this);
		}
	}

	/**
	 * Adds the given hot code replace listener to the collection of listeners
	 * that will be notified by the hot code replace manager in this plug-in.
	 * @param listener the listener to add
	 */
	public void addHotCodeReplaceListener(IJavaHotCodeReplaceListener listener) {
		JavaHotCodeReplaceManager.getDefault().addHotCodeReplaceListener(listener);
	}

	/**
	 * Removes the given hot code replace listener from the collection of
	 * listeners that will be notified by the hot code replace manager in this
	 * plug-in.
	 * @param listener the listener to remove
	 */
	public void removeHotCodeReplaceListener(IJavaHotCodeReplaceListener listener) {
		JavaHotCodeReplaceManager.getDefault().removeHotCodeReplaceListener(listener);
	}

	/**
	 * Shutdown the HCR manager and the Java debug targets.
	 *
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 * @see org.eclipse.core.runtime.Plugin#shutdown()
	 */
	@Override
	public void stop(BundleContext context) throws Exception {
		try {
			IEclipsePreferences node = InstanceScope.INSTANCE.getNode(getUniqueIdentifier());
			if(node != null) {
				node.removePreferenceChangeListener(this);
			}
			JavaHotCodeReplaceManager.getDefault().shutdown();
			ILaunchManager launchManager = DebugPlugin.getDefault()
					.getLaunchManager();
			IDebugTarget[] targets = launchManager.getDebugTargets();
			for (IDebugTarget target : targets) {
				if (target instanceof JDIDebugTarget) {
					((JDIDebugTarget) target).shutdown();
				}
			}
			fBreakpointListeners = null;
			ResourcesPlugin.getWorkspace().removeSaveParticipant(getUniqueIdentifier());
		} finally {
			fgPlugin = null;
			super.stop(context);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent)
	 */
	@Override
	public void preferenceChange(PreferenceChangeEvent event) {
		if (event.getKey().equals(JDIDebugModel.PREF_REQUEST_TIMEOUT)) {
			int value = Platform.getPreferencesService().getInt(
					JDIDebugPlugin.getUniqueIdentifier(),
					JDIDebugModel.PREF_REQUEST_TIMEOUT,
					JDIDebugModel.DEF_REQUEST_TIMEOUT,
					null);
			IDebugTarget[] targets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets();
			for (IDebugTarget target : targets) {
				if (target instanceof IJavaDebugTarget) {
					((IJavaDebugTarget) target).setRequestTimeout(value);
				}
			}
		}
	}

	/**
	 * Logs the specified {@link Throwable} with this plug-in's log.
	 *
	 * @param t {@link Throwable} to log
	 */
	public static void log(Throwable t) {
		Throwable top = t;
		if (t instanceof CoreException) {
			CoreException de = (CoreException) t;
			IStatus status = de.getStatus();
			if (status.getException() != null) {
				top = status.getException();
			}
		}
		// this message is intentionally not internationalized, as an exception
		// may be due to the resource bundle itself
		log(new Status(IStatus.ERROR, getUniqueIdentifier(), INTERNAL_ERROR,
				"Internal error logged from JDI Debug: ", top)); //$NON-NLS-1$
	}

	/**
	 * Logs the specified status with this plug-in's log.
	 *
	 * @param status
	 *            status to log
	 */
	public static void log(IStatus status) {
		getDefault().getLog().log(status);
	}

	/**
	 * @param breakpoint the breakpoint with problems
	 * @param errors the error set to notify about
	 * @see IJavaBreakpointListener#breakpointHasRuntimeException(IJavaLineBreakpoint,
	 *      DebugException)
	 */
	public void fireBreakpointHasCompilationErrors(IJavaLineBreakpoint breakpoint, Message[] errors) {
		getBreakpointNotifier().notify(null, breakpoint, COMPILATION_ERRORS, errors, null);
	}

	/**
	 * @param breakpoint the breakpoint with problems
	 * @param exception the exception to notify about
	 * @see IJavaBreakpointListener#breakpointHasCompilationErrors(IJavaLineBreakpoint, Message[])
	 */
	public void fireBreakpointHasRuntimeException(IJavaLineBreakpoint breakpoint, DebugException exception) {
		getBreakpointNotifier().notify(null, breakpoint, RUNTIME_EXCEPTION, null, exception);
	}

	/**
	 * Adds the given breakpoint listener to the JDI debug model.
	 *
	 * @param listener
	 *            breakpoint listener
	 */
	public void addJavaBreakpointListener(IJavaBreakpointListener listener) {
		fBreakpointListeners.add(listener);
	}

	/**
	 * Removes the given breakpoint listener from the JDI debug model.
	 *
	 * @param listener
	 *            breakpoint listener
	 */
	public void removeJavaBreakpointListener(IJavaBreakpointListener listener) {
		fBreakpointListeners.remove(listener);
	}

	/**
	 * Notifies listeners that the given breakpoint is about to be added.
	 *
	 * @param target
	 *            Java debug target
	 * @param breakpoint
	 *            Java breakpoint
	 */
	public void fireBreakpointAdding(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint) {
		getBreakpointNotifier().notify(target, breakpoint, ADDING, null, null);
	}

	/**
	 * Notifies listeners that the given breakpoint has been installed.
	 *
	 * @param target
	 *            Java debug target
	 * @param breakpoint
	 *            Java breakpoint
	 */
	public void fireBreakpointInstalled(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint) {
		getBreakpointNotifier().notify(target, breakpoint, INSTALLED, null,
				null);
	}

	/**
	 * Notifies listeners that the given breakpoint has been removed.
	 *
	 * @param target
	 *            Java debug target
	 * @param breakpoint
	 *            Java breakpoint
	 */
	public void fireBreakpointRemoved(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint) {
		getBreakpointNotifier().notify(target, breakpoint, REMOVED, null, null);
	}

	/**
	 * Notifies listeners that the given breakpoint has been hit. Returns
	 * whether the thread should suspend.
	 *
	 * @param thread the current thread context
	 * @param breakpoint Java breakpoint
	 * @return if the thread should suspend
	 */
	public boolean fireBreakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
		return getHitNotifier().notifyHit(thread, breakpoint);
	}

	/**
	 * Notifies listeners that the given breakpoint is about to be installed in
	 * the given type. Returns whether the breakpoint should be installed.
	 *
	 * @param target
	 *            Java debug target
	 * @param breakpoint
	 *            Java breakpoint
	 * @param type
	 *            the type the breakpoint is about to be installed in
	 * @return whether the breakpoint should be installed
	 */
	public boolean fireInstalling(IJavaDebugTarget target,
			IJavaBreakpoint breakpoint, IJavaType type) {
		return getInstallingNotifier().notifyInstalling(target, breakpoint,
				type);
	}

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

	abstract class AbstractNotifier implements ISafeRunnable {

		private IJavaBreakpoint fBreakpoint;
		private IJavaBreakpointListener fListener;

		/**
		 * Iterates through listeners calling this notifier's safe runnable.
		 * @param breakpoint the breakpoint to notify about
		 */
		protected void notifyListeners(IJavaBreakpoint breakpoint) {
			fBreakpoint = breakpoint;
			String[] ids = null;
			try {
				ids = breakpoint.getBreakpointListeners();
			} catch (CoreException e) {
				JDIDebugPlugin.log(e);
			}
			// breakpoint specific listener extensions
			if (ids != null && ids.length > 0) {
				for (String id : ids) {
					fListener = fJavaBreakpointManager
							.getBreakpointListener(id);
					if (fListener != null) {
						SafeRunner.run(this);
					}
				}
			}
			// global listener extensions
			IJavaBreakpointListener[] global = fJavaBreakpointManager
					.getGlobalListeners();
			if (global.length > 0) {
				for (IJavaBreakpointListener element : global) {
					fListener = element;
					SafeRunner.run(this);
				}
			}
			// programmatic global listeners
			for (IJavaBreakpointListener listener : fBreakpointListeners) {
				fListener = listener;
				SafeRunner.run(this);
			}
			fBreakpoint = null;
			fListener = null;
		}

		/**
		 * Returns the breakpoint for which notification is proceeding or
		 * <code>null</code> if not in notification.
		 *
		 * @return breakpoint or <code>null</code>
		 */
		protected IJavaBreakpoint getBreakpoint() {
			return fBreakpoint;
		}

		/**
		 * Returns the listener for which notification is proceeding or
		 * <code>null</code> if not in notification loop.
		 *
		 * @return breakpoint listener or <code>null</code>
		 */
		protected IJavaBreakpointListener getListener() {
			return fListener;
		}
	}

	class BreakpointNotifier extends AbstractNotifier {

		private IJavaDebugTarget fTarget;
		private int fKind;
		private Message[] fErrors;
		private DebugException fException;

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			switch (fKind) {
			case ADDING:
				getListener().addingBreakpoint(fTarget, getBreakpoint());
				break;
			case INSTALLED:
				getListener().breakpointInstalled(fTarget, getBreakpoint());
				break;
			case REMOVED:
				getListener().breakpointRemoved(fTarget, getBreakpoint());
				break;
			case COMPILATION_ERRORS:
				getListener().breakpointHasCompilationErrors(
						(IJavaLineBreakpoint) getBreakpoint(), fErrors);
				break;
			case RUNTIME_EXCEPTION:
				getListener().breakpointHasRuntimeException(
						(IJavaLineBreakpoint) getBreakpoint(), fException);
				break;
			}
		}

		/**
		 * Notifies listeners of the given addition, install, or remove.
		 *
		 * @param target
		 *            debug target
		 * @param breakpoint
		 *            the associated breakpoint
		 * @param kind
		 *            one of ADDED, REMOVED, INSTALLED
		 * @param errors
		 *            associated errors, or <code>null</code> if none
		 * @param exception
		 *            associated exception, or <code>null</code> if none
		 */
		public void notify(IJavaDebugTarget target, IJavaBreakpoint breakpoint,
				int kind, Message[] errors, DebugException exception) {
			fTarget = target;
			fKind = kind;
			fErrors = errors;
			fException = exception;
			notifyListeners(breakpoint);
			fTarget = null;
			fErrors = null;
			fException = null;
		}
	}

	private InstallingNotifier getInstallingNotifier() {
		return new InstallingNotifier();
	}

	class InstallingNotifier extends AbstractNotifier {

		private IJavaDebugTarget fTarget;
		private IJavaType fType;
		private int fInstall;

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			fInstall = fInstall
					| getListener().installingBreakpoint(fTarget,
							getBreakpoint(), fType);
		}

		private void dispose() {
			fTarget = null;
			fType = null;
		}

		/**
		 * Notifies listeners that the given breakpoint is about to be installed
		 * in the given type. Returns whether the breakpoint should be
		 * installed.
		 *
		 * @param target
		 *            Java debug target
		 * @param breakpoint
		 *            Java breakpoint
		 * @param type
		 *            the type the breakpoint is about to be installed in
		 * @return whether the breakpoint should be installed
		 */
		public boolean notifyInstalling(IJavaDebugTarget target,
				IJavaBreakpoint breakpoint, IJavaType type) {
			fTarget = target;
			fType = type;
			fInstall = IJavaBreakpointListener.DONT_CARE;
			notifyListeners(breakpoint);
			dispose();
			// install if any listener voted to install, or if no one voted to
			// not install
			return (fInstall & IJavaBreakpointListener.INSTALL) > 0
					|| (fInstall & IJavaBreakpointListener.DONT_INSTALL) == 0;
		}
	}

	private HitNotifier getHitNotifier() {
		return new HitNotifier();
	}

	class HitNotifier extends AbstractNotifier {

		private IJavaThread fThread;
		private int fSuspend;

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
		 */
		@Override
		public void handleException(Throwable exception) {
		}

		/**
		 * @see org.eclipse.core.runtime.ISafeRunnable#run()
		 */
		@Override
		public void run() throws Exception {
			if (fThread instanceof JDIThread) {
				if (((JDIThread) fThread).hasClientRequestedSuspend()) {
					// abort notification to breakpoint listeners if a client
					// suspend
					// request is received
					fSuspend = fSuspend | IJavaBreakpointListener.SUSPEND;
					return;
				}
			}
			fSuspend = fSuspend
					| getListener().breakpointHit(fThread, getBreakpoint());
		}

		/**
		 * Notifies listeners that the given breakpoint has been hit. Returns
		 * whether the thread should suspend.
		 *
		 * @param thread
		 *            thread in which the breakpoint was hit
		 * @param breakpoint
		 *            Java breakpoint
		 * @return whether the thread should suspend
		 */
		public boolean notifyHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
			fThread = thread;
			fSuspend = IJavaBreakpointListener.DONT_CARE;
			notifyListeners(breakpoint);
			fThread = null;
			// Suspend if any listener voted to suspend or no one voted
			// "don't suspend"
			return (fSuspend & IJavaBreakpointListener.SUSPEND) > 0
					|| (fSuspend & IJavaBreakpointListener.DONT_SUSPEND) == 0;
		}
	}

	/**
	 * Returns an evaluation engine for the given project in the given debug
	 * target or <code>null</code> if target does not have a IJavaDebugTarget
	 * that is a JDIDebugTarget implementation.
	 *
	 * @param project java project
	 * @param target the debug target
	 * @return evaluation engine or <code>null</code>
	 */
	public IAstEvaluationEngine getEvaluationEngine(IJavaProject project,
			IJavaDebugTarget target) {
		// get adapter for those that wrapper us
		IJavaDebugTarget javaTarget = target
				.getAdapter(IJavaDebugTarget.class);
		if (javaTarget instanceof JDIDebugTarget) {
			return ((JDIDebugTarget) javaTarget).getEvaluationEngine(project);
		}
		return null;
	}
}
