/*******************************************************************************
 * 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;
	}
}
