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


import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.IBreakpointManagerListener;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.jdi.TimeoutException;
import org.eclipse.jdi.internal.VirtualMachineImpl;
import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaThreadGroup;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.debug.eval.EvaluationManager;
import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
import org.eclipse.jdt.internal.debug.core.EventDispatcher;
import org.eclipse.jdt.internal.debug.core.IJDIEventListener;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint;
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaLineBreakpoint;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.ThreadGroupReference;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.Type;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.ThreadDeathEvent;
import com.sun.jdi.event.ThreadStartEvent;
import com.sun.jdi.event.VMDeathEvent;
import com.sun.jdi.event.VMDisconnectEvent;
import com.sun.jdi.event.VMStartEvent;
import com.sun.jdi.request.ClassPrepareRequest;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager;

/**
 * Debug target for JDI debug model.
 */

public class JDIDebugTarget extends JDIDebugElement implements IJavaDebugTarget, ILaunchListener, IBreakpointManagerListener, IDebugEventSetListener {
		
	/**
	 * Threads contained in this debug target. When a thread
	 * starts it is added to the list. When a thread ends it
	 * is removed from the list.
	 */
	private ArrayList fThreads;
	
	/**
	 * List of thread groups in this target.
	 */
	private ArrayList fGroups;
	
	/**
	 * Associated system process, or <code>null</code> if not available.
	 */
	private IProcess fProcess;
	/**
	 * Underlying virtual machine.
	 */
	private VirtualMachine fVirtualMachine;
	/**
	 * Whether terminate is supported. Not all targets
	 * support terminate. For example, a VM that was attached
	 * to remotely may not allow the user to terminate it.
	 */
	private boolean fSupportsTerminate;
	/**
	 * Whether terminated
	 */
	private boolean fTerminated;
	
	/**
	 * Whether in the process of terminating
	 */
	private boolean fTerminating;
	/**
	 * Whether disconnected
	 */
	private boolean fDisconnected;
	/**
	 * Whether disconnect is supported.
	 */
	private boolean fSupportsDisconnect;
	/**
	 * Whether enable/disable object GC is allowed
	 */
	private boolean fSupportsDisableGC = false;
	/**
	 * Collection of breakpoints added to this target. Values are of type <code>IJavaBreakpoint</code>.
	 */
	private List fBreakpoints;
	
	/**
	 * Collection of types that have attempted HCR, but failed.
	 * The types are stored by their fully qualified names.
	 */
	private Set fOutOfSynchTypes;
	/**
	 * Whether or not this target has performed a hot code replace.
	 */
	private boolean fHasHCROccurred;
	
	/**
	 * The name of this target - set by the client on creation, or retrieved from the
	 * underlying VM.
	 */
	private String fName;

	/**
	 * The event dispatcher for this debug target, which runs in its
	 * own thread.
	 */
	private EventDispatcher fEventDispatcher= null;
	
	/**
	 * The thread start event handler
	 */
	private ThreadStartHandler fThreadStartHandler= null;
	
	/**
	 * Whether this VM is suspended.
	 */
	private boolean fSuspended = true;
	
	/**
	 * Whether the VM should be resumed on startup
	 */
	private boolean fResumeOnStartup = false; 
	
	/**
	 * The launch this target is contained in
	 */
	private ILaunch fLaunch;	
	
	/**
	 * Count of the number of suspend events in this target
	 */
	private int fSuspendCount = 0;
	
	/**
	 * Evaluation engine cache by Java project. Engines
	 * are disposed when this target terminates.
	 */
	private HashMap fEngines;
	
	/**
	 * List of step filters - each string is a pattern/fully qualified
	 * name of a type to filter.
	 */
	private String[] fStepFilters = null;
	
	/**
	 * Step filter state mask.
	 */
	private int fStepFilterMask = 0;
	
	/**
	 * Step filter bit mask - indicates if step filters are enabled.
	 */
	private static final int STEP_FILTERS_ENABLED = 0x001;
	
	/**
	 * Step filter bit mask - indicates if synthetic methods are filtered.
	 */	
	private static final int FILTER_SYNTHETICS = 0x002;
	
	/**
	 * Step filter bit mask - indicates if static initializers are filtered.
	 */		
	private static final int FILTER_STATIC_INITIALIZERS = 0x004;
	
	/**
	 * Step filter bit mask - indicates if constructors are filtered.
	 */		
	private static final int FILTER_CONSTRUCTORS = 0x008;
	
	/**
	 * When a step lands in a filtered location, this indicates whether stepping
	 * should proceed "through" to an un-filtered location or step return.
	 * @since 3.3
	 */
	private static final int STEP_THRU_FILTERS = 0x010;
	
	/**
	 * Mask used to flip individual bit masks via XOR
	 */
	private static final int XOR_MASK = 0xFFF;
	/**
	 * Whether this debug target is currently performing a hot code replace
	 */
	private boolean fIsPerformingHotCodeReplace= false;
	
	 
	/**
	 * Creates a new JDI debug target for the given virtual machine.
	 * 
	 * @param jvm the underlying VM
	 * @param name the name to use for this VM, or <code>null</code>
	 * 	if the name should be retrieved from the underlying VM
	 * @param supportsTerminate whether the terminate action
	 *  is supported by this debug target
	 * @param supportsDisconnect whether the disconnect action is
	 * 	supported by this debug target
	 * @param process the system process associated with the
	 * 	underlying VM, or <code>null</code> if no system process
	 *  is available (for example, a remote VM)
	 * @param resume whether the VM should be resumed on startup.
	 *  Has no effect if the VM is already resumed/running when
	 *  the connection is made.  
	 */
	public JDIDebugTarget(ILaunch launch, VirtualMachine jvm, String name, boolean supportTerminate, boolean supportDisconnect, IProcess process, boolean resume) {
		super(null);
		setLaunch(launch);
		setResumeOnStartup(resume);
		setSupportsTerminate(supportTerminate);
		setSupportsDisconnect(supportDisconnect);
		setVM(jvm);
		jvm.setDebugTraceMode(VirtualMachine.TRACE_NONE);
		setProcess(process);
		setTerminated(false);
		setTerminating(false);
		setDisconnected(false);
		setName(name);
		setBreakpoints(new ArrayList(5));
		setThreadList(new ArrayList(5));
		fGroups = new ArrayList(5);
		setOutOfSynchTypes(new ArrayList(0));
		setHCROccurred(false);
		initialize();
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
		DebugPlugin.getDefault().getBreakpointManager().addBreakpointManagerListener(this);
	}

	/**
	 * Returns the event dispatcher for this debug target.
	 * There is one event dispatcher per debug target.
	 * 
	 * @return event dispatcher
	 */
	public EventDispatcher getEventDispatcher() {
		return fEventDispatcher;
	}
	
	/**
	 * Sets the event dispatcher for this debug target.
	 * Set once at initialization.
	 * 
	 * @param dispatcher event dispatcher
	 * @see #initialize()
	 */
	private void setEventDispatcher(EventDispatcher dispatcher) {
		fEventDispatcher = dispatcher;
	}
	
	/**
	 * Returns an iterator over the collection of threads. The
	 * returned iterator is made on a copy of the thread list
	 * so that it is thread safe. This method should always be
	 * used instead of getThreadList().iterator()
	 * @return an iterator over the collection of threads
	 */
	private Iterator getThreadIterator() {
		List threadList;
		synchronized (fThreads) {
			threadList= (List) fThreads.clone();
		}
		return threadList.iterator();
	}
	
	/**
	 * Sets the list of threads contained in this debug target.
	 * Set to an empty collection on creation. Threads are
	 * added and removed as they start and end. On termination
	 * this collection is set to the immutable singleton empty list.
	 * 
	 * @param threads empty list
	 */
	private void setThreadList(ArrayList threads) {
		fThreads = threads;
	}
	
	/**
	 * Returns the collection of breakpoints installed in this
	 * debug target.
	 * 
	 * @return list of installed breakpoints - instances of 
	 * 	<code>IJavaBreakpoint</code>
	 */
	public List getBreakpoints() {
		return fBreakpoints;
	}
	
	/**
	 * Sets the list of breakpoints installed in this debug
	 * target. Set to an empty list on creation.
	 * 
	 * @param breakpoints empty list
	 */
	private void setBreakpoints(List breakpoints) {
		fBreakpoints = breakpoints;
	}
		
	/**
	 * Notifies this target that the underlying VM has started.
	 * This is the first event received from the VM.
	 * The VM is resumed. This event is not generated when
	 * an attach is made to a VM that is already running
	 * (has already started up). The VM is resumed as specified
	 * on creation.
	 * 
	 * @param event VM start event
	 */
	public void handleVMStart(VMStartEvent event) {
		if (isResumeOnStartup()) {
			try {
				setSuspended(true);
				resume();
			} catch (DebugException e) {
				logError(e);
			}
		}
		// If any threads have resumed since thread collection was initialized,
		// update their status (avoid concurrent modification - use #getThreads())
		IThread[] threads = getThreads();
		for (int i = 0; i < threads.length; i++) {
			JDIThread thread = (JDIThread)threads[i];
			if (thread.isSuspended()) {
				try {
					boolean suspended = thread.getUnderlyingThread().isSuspended();
					if (!suspended) {
						thread.setRunning(true);
						thread.fireResumeEvent(DebugEvent.CLIENT_REQUEST);
					}
				} catch (VMDisconnectedException e) {
				} catch (ObjectCollectedException e){
				} catch (RuntimeException e) {
					logError(e);
				}				
			}
		}
		
	}
	 
	/**
	 * Initialize event requests and state from the underlying VM.
	 * This method is synchronized to ensure that we do not start
	 * to process an events from the target until our state is
	 * initialized.
	 */
	protected synchronized void initialize() {
		setEventDispatcher(new EventDispatcher(this));
		setRequestTimeout(JDIDebugModel.getPreferences().getInt(JDIDebugModel.PREF_REQUEST_TIMEOUT));
		initializeRequests();
		initializeState();
		initializeBreakpoints();
		getLaunch().addDebugTarget(this);
        DebugPlugin plugin = DebugPlugin.getDefault();
		plugin.addDebugEventListener(this);
		fireCreationEvent();
		// begin handling/dispatching events after the creation event is handled by all listeners
		plugin.asyncExec(new Runnable() {
			public void run() {
				EventDispatcher dispatcher = getEventDispatcher();
		        if (dispatcher != null) {
		            Thread t= new Thread(dispatcher, JDIDebugModel.getPluginIdentifier() + JDIDebugModelMessages.JDIDebugTarget_JDI_Event_Dispatcher); 
		            t.setDaemon(true);
		            t.start();
		        }
			}
		});
	}
	
	/**
	 * Adds all of the pre-existing threads to this debug target.  
	 */
	protected void initializeState() {

		List threads= null;
		VirtualMachine vm = getVM();
		if (vm != null) {
			try {
				String name = vm.name();
				fSupportsDisableGC = !name.equals("Classic VM"); //$NON-NLS-1$
			} catch (RuntimeException e) {
				internalError(e);
			}
			try {
				threads= vm.allThreads();
			} catch (RuntimeException e) {
				internalError(e);
			}
			if (threads != null) {
				Iterator initialThreads= threads.iterator();
				while (initialThreads.hasNext()) {
					createThread((ThreadReference) initialThreads.next());
				}
			}			
		}
		
		if (isResumeOnStartup()) {
			setSuspended(false);
		}
	}
	 
	/**
	 * Registers event handlers for thread creation,
	 * thread termination.
	 */
	protected void initializeRequests() {
		setThreadStartHandler(new ThreadStartHandler());
		new ThreadDeathHandler();		
	}

	/**
	 * Installs all Java breakpoints that currently exist in
	 * the breakpoint manager
	 */
	protected void initializeBreakpoints() {
		IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager();
		manager.addBreakpointListener(this);
		IBreakpoint[] bps = manager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
		for (int i = 0; i < bps.length; i++) {
			if (bps[i] instanceof IJavaBreakpoint) {
				breakpointAdded(bps[i]);
			}
		}
	}
		
	/**
	 * Creates, adds and returns a thread for the given
	 * underlying thread reference. A creation event
	 * is fired for the thread.
	 * Returns <code>null</code> if during the creation of the thread this target
	 * is set to the disconnected state.
	 * 
	 * @param thread underlying thread
	 * @return model thread
	 */
	protected JDIThread createThread(ThreadReference thread) {
		JDIThread jdiThread= newThread(thread);
		if (jdiThread == null) {
			return null;
		}
		if (isDisconnected()) {
			return null;
		}
		synchronized (fThreads) {
			fThreads.add(jdiThread);
		}
		jdiThread.fireCreationEvent();
		return jdiThread;
	}
	
	/**
	 * Factory method for creating new threads. Creates and returns a new thread
	 * object for the underlying thread reference, or <code>null</code> if none
	 * 
	 * @param reference thread reference
	 * @return JDI model thread
	 */
	protected JDIThread newThread(ThreadReference reference) {
		try {
			return new JDIThread(this, reference);
		} catch (ObjectCollectedException exception) {
			// ObjectCollectionException can be thrown if the thread has already
			// completed (exited) in the VM.
		}
		return null;
	}
	
	/**
	 * @see IDebugTarget#getThreads()
	 */
	public IThread[] getThreads() {
		synchronized (fThreads) {
			return (IThread[])fThreads.toArray(new IThread[0]);
		}
	}
	
	/**
	 * @see ISuspendResume#canResume()
	 */
	public boolean canResume() {
		return (isSuspended() || hasSuspendedThreads())
		    && isAvailable() && !isPerformingHotCodeReplace();
	}

	/**
	 * Returns whether this target has any threads which are suspended.
	 * @return true if any thread is suspended, false otherwise
	 * @since 3.2
	 */
	private boolean hasSuspendedThreads() {
		Iterator it = getThreadIterator();
		while(it.hasNext()){
			IThread thread = (IThread)it.next();
			if(thread.isSuspended())
				return true;
		}
		return false;
	}

	/**
	 * @see ISuspendResume#canSuspend()
	 */
	public boolean canSuspend() {
		if (!isSuspended() && isAvailable()) {
			// only allow suspend if no threads are currently suspended
			IThread[] threads= getThreads();
			for (int i= 0, numThreads= threads.length; i < numThreads; i++) {
				if (((JDIThread)threads[i]).isSuspended()) {
					return false;
				}
			}
			return true;
		}
		return false;
	}

	/**
	 * @see ITerminate#canTerminate()
	 */
	public boolean canTerminate() {
		return supportsTerminate() && isAvailable();
	}

	/**
	 * @see IDisconnect#canDisconnect()
	 */
	public boolean canDisconnect() {
		return supportsDisconnect() && !isDisconnected();
	}
	
	/**
	 * Returns whether this debug target supports disconnecting.
	 * 
	 * @return whether this debug target supports disconnecting
	 */
	protected boolean supportsDisconnect() {
		return fSupportsDisconnect;
	}
	
	/**
	 * Sets whether this debug target supports disconnection.
	 * Set on creation.
	 * 
	 * @param supported <code>true</code> if this target supports
	 * 	disconnection, otherwise <code>false</code>
	 */
	private void setSupportsDisconnect(boolean supported) {
		fSupportsDisconnect = supported;
	}
	
	/**
	 * Returns whether this debug target supports termination.
	 * 
	 * @return whether this debug target supports termination
	 */
	protected boolean supportsTerminate() {
		return fSupportsTerminate;
	}
	
	/**
	 * Sets whether this debug target supports termination.
	 * Set on creation.
	 * 
	 * @param supported <code>true</code> if this target supports
	 * 	termination, otherwise <code>false</code>
	 */
	private void setSupportsTerminate(boolean supported) {
		fSupportsTerminate = supported;
	}
	
	/**
	 * @see IJavaDebugTarget#supportsHotCodeReplace()
	 */
	public boolean supportsHotCodeReplace() {
		return supportsJ9HotCodeReplace() || supportsJDKHotCodeReplace();
	}
	
	/**
	 * @see IJavaDebugTarget#supportsInstanceBreakpoints()
	 */
	public boolean supportsInstanceBreakpoints() {
		if (isAvailable() && JDIDebugPlugin.isJdiVersionGreaterThanOrEqual(new int[] {1,4})) {
			VirtualMachine vm = getVM();
			if (vm != null) {
				return vm.canUseInstanceFilters();
			}
		}
		return false;
	}
	
	/**
	 * Returns whether this debug target supports hot code replace for the J9 VM.
	 * 
	 * @return whether this debug target supports J9 hot code replace
	 */
	public boolean supportsJ9HotCodeReplace() {
		VirtualMachine vm = getVM();
		if (isAvailable() && vm instanceof org.eclipse.jdi.hcr.VirtualMachine) {
			try {
				return ((org.eclipse.jdi.hcr.VirtualMachine)vm).canReloadClasses();
			} catch (UnsupportedOperationException e) {
				// This is not an error condition - UnsupportedOperationException is thrown when a VM does
				// not support HCR
			}
		}
		return false;
	}
	
	/**
	 * Returns whether this debug target supports hot code replace for JDK VMs.
	 * 
	 * @return whether this debug target supports JDK hot code replace
	 */
	public boolean supportsJDKHotCodeReplace() {
		if (isAvailable() && JDIDebugPlugin.isJdiVersionGreaterThanOrEqual(new int[] {1,4})) {
			VirtualMachine vm = getVM();
			if (vm != null) {
				return vm.canRedefineClasses();
			}
		}
		return false;
	}
	
	/**
	 * Returns whether this debug target supports popping stack frames.
	 * 
	 * @return whether this debug target supports popping stack frames.
	 */
	public boolean canPopFrames() {
		if (isAvailable() && JDIDebugPlugin.isJdiVersionGreaterThanOrEqual(new int[] {1,4})) {
			VirtualMachine vm = getVM();
			if (vm != null) {
				return vm.canPopFrames();
			}
		}
		return false;
	}

	/**
	 * @see IDisconnect#disconnect()
	 */
	public void disconnect() throws DebugException {

		if (!isAvailable()) {
			// already done
			return;
		}

		if (!canDisconnect()) {
			notSupported(JDIDebugModelMessages.JDIDebugTarget_does_not_support_disconnect); 
		}

		try {
			disposeThreadHandler();
			VirtualMachine vm = getVM();
			if (vm != null) {
				vm.dispose();
			}
		} catch (VMDisconnectedException e) {
			// if the VM disconnects while disconnecting, perform
			// normal disconnect handling
			disconnected();
		} catch (RuntimeException e) {
			targetRequestFailed(MessageFormat.format(JDIDebugModelMessages.JDIDebugTarget_exception_disconnecting, new String[] {e.toString()}), e); 
		}

	}
	
	/**
	 * Allows for ThreadStartHandler to do clean up/disposal.
	 */
	private void disposeThreadHandler() {
		ThreadStartHandler handler = getThreadStartHandler();
		if (handler != null) {
			handler.deleteRequest();
		}
	}

	/**
	 * Returns the underlying virtual machine associated with this
	 * debug target, or <code>null</code> if none (disconnected/terminated)
	 * 
	 * @return the underlying VM or <code>null</code>
	 */
	public VirtualMachine getVM() {
		return fVirtualMachine;
	}
	
	/**
	 * Sets the underlying VM associated with this debug
	 * target. Set on creation.
	 * 
	 * @param vm underlying VM
	 */
	private void setVM(VirtualMachine vm) {
		fVirtualMachine = vm;
	}
	
	/**
	 * Sets whether this debug target has performed a hot
	 * code replace.
	 */
	public void setHCROccurred(boolean occurred) {
		fHasHCROccurred= occurred;
	}
	
	public void removeOutOfSynchTypes(List qualifiedNames) {
		fOutOfSynchTypes.removeAll(qualifiedNames);
	}
	
	/**
	 * Sets the list of out of synch types
	 * to the given list.
	 */
	private void setOutOfSynchTypes(List qualifiedNames) {
		fOutOfSynchTypes= new HashSet();
		fOutOfSynchTypes.addAll(qualifiedNames);
	}
	
	/**
	 * The given types have failed to be reloaded by HCR.
	 * Add them to the list of out of synch types.
	 */
	public void addOutOfSynchTypes(List qualifiedNames) {
		fOutOfSynchTypes.addAll(qualifiedNames);
	}
	
	/**
	 * Returns whether the given type is out of synch in this
	 * target.
	 */
	public boolean isOutOfSynch(String qualifiedName) {
		if (fOutOfSynchTypes == null || fOutOfSynchTypes.isEmpty()) {
			return false;
		}
		return fOutOfSynchTypes.contains(qualifiedName);
	}
	
	/**
	 * @see IJavaDebugTarget#isOutOfSynch()
	 */
	public boolean isOutOfSynch() throws DebugException {
		Iterator threads= getThreadIterator();
		while (threads.hasNext()) {
			JDIThread thread= (JDIThread)threads.next();
			if (thread.isOutOfSynch()) {
				return true;
			}
		}
		return false;
	}	
	
	/**
	 * @see IJavaDebugTarget#mayBeOutOfSynch()
	 */
	public boolean mayBeOutOfSynch() {
		Iterator threads= getThreadIterator();
		while (threads.hasNext()) {
			JDIThread thread= (JDIThread)threads.next();
			if (thread.mayBeOutOfSynch()) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Returns whether a hot code replace attempt has failed.
	 * 
	 * HCR has failed if there are any out of synch types
	 */
	public boolean hasHCRFailed() {
		return fOutOfSynchTypes != null && !fOutOfSynchTypes.isEmpty();
	}
	
	/**
	 * Returns whether this debug target has performed
	 * a hot code replace
	 */
	public boolean hasHCROccurred() {
		return fHasHCROccurred;
	}
	
	/**
	 * Reinstall all breakpoints installed in the given resources
	 */
	public void reinstallBreakpointsIn(List resources, List classNames) {
		List breakpoints= getBreakpoints();
		IJavaBreakpoint[] copy= new IJavaBreakpoint[breakpoints.size()];
		breakpoints.toArray(copy);
		IJavaBreakpoint breakpoint= null;
		String installedType= null;
		
		for (int i= 0; i < copy.length; i++) {
			breakpoint= copy[i];
			if (breakpoint instanceof JavaLineBreakpoint) {
				try {
					installedType= breakpoint.getTypeName();
					if (classNames.contains(installedType)) {
						breakpointRemoved(breakpoint, null);
						breakpointAdded(breakpoint);
					}
				} catch (CoreException ce) {
					logError(ce);
					continue;
				}
			}
		}		
	}

	/**
	 * Finds and returns the JDI thread for the associated thread reference, 
	 * or <code>null</code> if not found.
	 * 
	 * @param the underlying thread reference
	 * @return the associated model thread
	 */
	public JDIThread findThread(ThreadReference tr) {
		Iterator iter= getThreadIterator();
		while (iter.hasNext()) {
			JDIThread thread = (JDIThread) iter.next();
			if (thread.getUnderlyingThread().equals(tr))
				return thread;
		}
		return null;
	}

	/**
	 * @see IDebugElement#getName()
	 */
	public String getName() throws DebugException {
		if (fName == null) {
			setName(getVMName());
		}
		return fName;
	}
	
	/**
	 * Sets the name of this debug target. Set on creation,
	 * and if set to <code>null</code> the name will be
	 * retrieved lazily from the underlying VM.
	 * 
	 * @param name the name of this VM or <code>null</code>
	 * 	if the name should be retrieved from the underlying VM
	 */
	protected void setName(String name) {
		fName = name;
	}
	
	/**
	 * Sets the process associated with this debug target,
	 * possibly <code>null</code>. Set on creation.
	 * 
	 * @param process the system process associated with the
	 * 	underlying VM, or <code>null</code> if no process is
	 * 	associated with this debug target (for example, a remote
	 * 	VM).
	 */
	protected void setProcess(IProcess process) {
		fProcess = process;
	}
	
	/**
	 * @see IDebugTarget#getProcess()
	 */
	public IProcess getProcess() {
		return fProcess;
	}
	
	/**
	 * Notification the underlying VM has died. Updates
	 * the state of this target to be terminated.
	 * 
	 * @param event VM death event
	 */
	public void handleVMDeath(VMDeathEvent event) {
		terminated();
	}

	/**
	 * Notification the underlying VM has disconnected.
	 * Updates the state of this target to be terminated.
	 * 
	 * @param event disconnect event
	 */
	public void handleVMDisconnect(VMDisconnectEvent event) {
		if (isTerminating()) {
			terminated();
		} else {
			disconnected();
		}
	}
	
	/**
	 * @see ISuspendResume#isSuspended()
	 */
	public boolean isSuspended() {
		return fSuspended;
	}
	
	/**
	 * Sets whether this VM is suspended.
	 * 
	 * @param suspended whether this VM is suspended
	 */
	private void setSuspended(boolean suspended) {
		fSuspended = suspended;
	}
	
	/**
	 * Returns whether this target is available to
	 * handle VM requests
	 */
	public boolean isAvailable() {
		return !(isTerminated() || isTerminating() || isDisconnected());
	}

	/**
	 * @see ITerminate#isTerminated()
	 */
	public boolean isTerminated() {
		return fTerminated;
	}

	/**
	 * Sets whether this debug target is terminated
	 * 
	 * @param terminated <code>true</code> if this debug
	 * 	target is terminated, otherwise <code>false</code>
	 */
	protected void setTerminated(boolean terminated) {
		fTerminated = terminated;
	}
	
	/**
	 * Sets whether this debug target is disconnected
	 * 
	 * @param disconnected <code>true</code> if this debug
	 *  target is disconnected, otherwise <code>false</code>
	 */
	protected void setDisconnected(boolean disconnected) {
		fDisconnected= disconnected;
	}
	
	/**
	 * @see IDisconnect#isDisconnected()
	 */
	public boolean isDisconnected() {
		return fDisconnected;
	}
	
	/**
	 * Creates, enables and returns a class prepare request for the
	 * specified class name in this target.
	 * 
	 * @param classPattern regular expression specifying the pattern of
	 * 	class names that will cause the event request to fire. Regular
	 * 	expressions may begin with a '*', end with a '*', or be an exact
	 * 	match.
	 * @exception CoreException if unable to create the request
	 */	
	public ClassPrepareRequest createClassPrepareRequest(String classPattern) throws CoreException {
		return createClassPrepareRequest(classPattern, null);
	}
	
	/**
	 * Creates, enables and returns a class prepare request for the
	 * specified class name in this target. Can specify a class exclusion filter
	 * as well.
	 * This is a utility method used by event requesters that need to
	 * create class prepare requests.
	 * 
	 * @param classPattern regular expression specifying the pattern of
	 * 	class names that will cause the event request to fire. Regular
	 * 	expressions may begin with a '*', end with a '*', or be an exact
	 * 	match.
	 *  @param classExclusionPattern regular expression specifying the pattern of
	 * 	class names that will not cause the event request to fire. Regular
	 * 	expressions may begin with a '*', end with a '*', or be an exact
	 * 	match.  May be <code>null</code>.
	 * @exception CoreException if unable to create the request
	 */
	public ClassPrepareRequest createClassPrepareRequest(String classPattern, String classExclusionPattern) throws CoreException {
		return createClassPrepareRequest(classPattern, classExclusionPattern, true);
	}
	
	/**
	 * Creates, enables and returns a class prepare request for the
	 * specified class name in this target. Can specify a class exclusion filter
	 * as well.
	 * This is a utility method used by event requesters that need to
	 * create class prepare requests.
	 * 
	 * @param classPattern regular expression specifying the pattern of
	 * 	class names that will cause the event request to fire. Regular
	 * 	expressions may begin with a '*', end with a '*', or be an exact
	 * 	match.
	 *  @param classExclusionPattern regular expression specifying the pattern of
	 * 	class names that will not cause the event request to fire. Regular
	 * 	expressions may begin with a '*', end with a '*', or be an exact
	 * 	match.  May be <code>null</code>.
	 * @param enabled whether to enable the event request
	 * @exception CoreException if unable to create the request
	 * @since 3.3
	 */
	public ClassPrepareRequest createClassPrepareRequest(String classPattern, String classExclusionPattern, boolean enabled) throws CoreException {
		return createClassPrepareRequest(classPattern, classExclusionPattern, enabled, null);
	}
	
	/**
	 * Creates, enables and returns a class prepare request for the
	 * specified class name in this target. Can specify a class exclusion filter
	 * as well.
	 * This is a utility method used by event requesters that need to
	 * create class prepare requests.
	 * 
	 * @param classPattern regular expression specifying the pattern of
	 * 	class names that will cause the event request to fire. Regular
	 * 	expressions may begin with a '*', end with a '*', or be an exact
	 * 	match. May be <code>null</code> if sourceName is specified
	 *  @param classExclusionPattern regular expression specifying the pattern of
	 * 	class names that will not cause the event request to fire. Regular
	 * 	expressions may begin with a '*', end with a '*', or be an exact
	 * 	match.  May be <code>null</code>.
	 * @param enabled whether to enable the event request
	 * @param sourceName source name pattern to match or <code>null</code> if classPattern
	 *  is specified
	 * @exception CoreException if unable to create the request
	 * @since 3.3
	 */
	public ClassPrepareRequest createClassPrepareRequest(String classPattern, String classExclusionPattern, boolean enabled, String sourceName) throws CoreException {
		EventRequestManager manager= getEventRequestManager();
		if (!isAvailable() || manager == null) {
			requestFailed(JDIDebugModelMessages.JDIDebugTarget_Unable_to_create_class_prepare_request___VM_disconnected__2, null); 
		}
		ClassPrepareRequest req= null;
		try {
			req= manager.createClassPrepareRequest();
			if (classPattern != null) {
				req.addClassFilter(classPattern);
			}
			if (classExclusionPattern != null) {
				req.addClassExclusionFilter(classExclusionPattern);
			}
			req.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
			if (sourceName != null) {
				req.addSourceNameFilter(sourceName);
			}
			if (enabled) {
				req.enable();
			}
		} catch (RuntimeException e) {
			targetRequestFailed(JDIDebugModelMessages.JDIDebugTarget_Unable_to_create_class_prepare_request__3, e); 
			// execution will not reach here
			return null;
		}
		return req;
	}

	/**
	 * @see ISuspendResume#resume()
	 */
	public void resume() throws DebugException {
		// if a client calls resume, then we should resume on a VMStart event in case
		// it has not yet been received, and the target was created with the "resume"
		// flag as "false". See bug 32372.		
		setResumeOnStartup(true);
		resume(true);		
	}
	
	/**
	 * @see ISuspendResume#resume()
	 * 
	 * Updates the state of this debug target to resumed,
	 * but does not fire notification of the resumption.
	 */
	public void resumeQuiet() throws DebugException {
		resume(false);
	}
	
	/**
	 * @see ISuspendResume#resume()
	 * 
	 * Updates the state of this debug target, but only fires
	 * notification to listeners if <code>fireNotification</code>
	 * is <code>true</code>.
	 */
	protected void resume(boolean fireNotification) throws DebugException {
		if ((!isSuspended() && !hasSuspendedThreads()) 
			|| !isAvailable()) {
			return;
		}
		try {
			setSuspended(false);
			resumeThreads();
			VirtualMachine vm = getVM();
			if (vm != null) {
				vm.resume();
			}
			if (fireNotification) {
				fireResumeEvent(DebugEvent.CLIENT_REQUEST);
			}
		} catch (VMDisconnectedException e) {
			disconnected();
			return;
		} catch (RuntimeException e) {
			setSuspended(true);
			fireSuspendEvent(DebugEvent.CLIENT_REQUEST);
			targetRequestFailed(MessageFormat.format(JDIDebugModelMessages.JDIDebugTarget_exception_resume, new String[] {e.toString()}), e); 
		}	
	}
	
	/**
	 * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(IBreakpoint)
	 */
	public boolean supportsBreakpoint(IBreakpoint breakpoint) {
		return breakpoint instanceof IJavaBreakpoint;
	}

	/**
	 * Notification a breakpoint has been added to the
	 * breakpoint manager. If the breakpoint is a Java
	 * breakpoint and this target is not terminated,
	 * the breakpoint is installed.
	 * 
	 * @param breakpoint the breakpoint added to
	 * 	the breakpoint manager
	 */
	public void breakpointAdded(IBreakpoint breakpoint) {
		if (!isAvailable()) {
			return;
		}
		if (supportsBreakpoint(breakpoint)) {
			try {
				JavaBreakpoint javaBreakpoint= (JavaBreakpoint) breakpoint;
				if (!getBreakpoints().contains(breakpoint)) {
					if (!javaBreakpoint.shouldSkipBreakpoint()) {
						// If the breakpoint should be skipped, don't add the breakpoint
						// request to the VM. Just add the breakpoint to the collection so
						// we have it if the manager is later enabled.
						javaBreakpoint.addToTarget(this);
					}					
					getBreakpoints().add(breakpoint);
				}
			} catch (CoreException e) {
				logError(e);
			}
		}
	}

	/**
	 * Notification that one or more attributes of the
	 * given breakpoint has changed. If the breakpoint
	 * is a Java breakpoint, the associated event request
	 * in the underlying VM is updated to reflect the
	 * new state of the breakpoint.
	 * 
	 * @param breakpoint the breakpoint that has changed
	 */
	public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
	}
	
	/**
	 * Notification that the given breakpoint has been removed
	 * from the breakpoint manager. If this target is not terminated,
	 * the breakpoint is removed from the underlying VM.
	 * 
	 * @param breakpoint the breakpoint has been removed from
	 *  the breakpoint manager.
	 */
	public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
		if (!isAvailable()) {
			return;
		}		
		if (supportsBreakpoint(breakpoint)) {
			try {
				((JavaBreakpoint)breakpoint).removeFromTarget(this);
				getBreakpoints().remove(breakpoint);
				Iterator threads = getThreadIterator();
				while (threads.hasNext()) {
					((JDIThread)threads.next()).removeCurrentBreakpoint(breakpoint);
				}
			} catch (CoreException e) {
				logError(e);
			}
		}
	}

	/**
	 * @see ISuspendResume
	 */
	public void suspend() throws DebugException {
		if (isSuspended()) {
			return;
		}
		try {
			VirtualMachine vm = getVM();
			if (vm != null) {
				vm.suspend();
			}
			suspendThreads();
			setSuspended(true);
			fireSuspendEvent(DebugEvent.CLIENT_REQUEST);
		} catch (RuntimeException e) {
			setSuspended(false);
			fireResumeEvent(DebugEvent.CLIENT_REQUEST);
			targetRequestFailed(MessageFormat.format(JDIDebugModelMessages.JDIDebugTarget_exception_suspend, new String[] {e.toString()}), e); 
		}
		
	}
	
	/**
	 * Notifies threads that they have been suspended
	 */
	protected void suspendThreads() {
		Iterator threads = getThreadIterator();
		while (threads.hasNext()) {
			((JDIThread)threads.next()).suspendedByVM();
		}
	}

	/**
	 * Notifies threads that they have been resumed
	 */
	protected void resumeThreads() throws DebugException {
		Iterator threads = getThreadIterator();
		while (threads.hasNext()) {
			((JDIThread)threads.next()).resumedByVM();
		}
	}
	
	/**
	 * Notifies this VM to update its state in preparation
	 * for a suspend.
	 * 
	 * @param breakpoint the breakpoint that caused the
	 *  suspension
	 */
	public void prepareToSuspendByBreakpoint(JavaBreakpoint breakpoint) {
		setSuspended(true);
		suspendThreads();
	}
	
	/**
	 * Notifies this VM it has been suspended by the
	 * given breakpoint
	 * 
	 * @param breakpoint the breakpoint that caused the
	 *  suspension
	 */
	protected void suspendedByBreakpoint(JavaBreakpoint breakpoint, boolean queueEvent) {
		if (queueEvent) {
			queueSuspendEvent(DebugEvent.BREAKPOINT);
		} else {
			fireSuspendEvent(DebugEvent.BREAKPOINT);
		}
	}	
	
	/**
	 * Notifies this VM suspension has been cancelled
	 * 
	 * @param breakpoint the breakpoint that caused the
	 *  suspension
	 */
	protected void cancelSuspendByBreakpoint(JavaBreakpoint breakpoint) throws DebugException {
		setSuspended(false);
		resumeThreads();
	}	

	/**
	 * @see ITerminate#terminate()
	 */
	public void terminate() throws DebugException {
		if (!isAvailable()) {
			return;
		}
		if (!supportsTerminate()) {
			notSupported(JDIDebugModelMessages.JDIDebugTarget_does_not_support_termination); 
		}
		try {
			setTerminating(true);
			disposeThreadHandler();
			VirtualMachine vm = getVM();
			if (vm != null) {
				vm.exit(1);
			}
			IProcess process= getProcess();
			if (process != null) {
				process.terminate();
			}
		} catch (VMDisconnectedException e) {
			// if the VM disconnects while exiting, perform 
			// normal termination processing
			terminated();
		} catch (TimeoutException exception) {
			// if there is a timeout see if the associated process is terminated
			IProcess process = getProcess();
			if (process != null && process.isTerminated()) {
				terminated();
			} else {
				// All we can do is disconnect
				disconnected();
			}
		} catch (RuntimeException e) {
			targetRequestFailed(MessageFormat.format(JDIDebugModelMessages.JDIDebugTarget_exception_terminating, new String[] {e.toString()}), e); 
		}
	}

	/**
	 * Updates the state of this target to be terminated,
	 * if not already terminated.
	 */
	protected void terminated() {
		setTerminating(false);
		if (!isTerminated()) {
			setTerminated(true);
			setDisconnected(true);
			cleanup();
			fireTerminateEvent();
		}
	}
	
	/**
	 * Updates the state of this target for disconnection
	 * from the VM.
	 */
	protected void disconnected() {
		if (!isDisconnected()) {
			setDisconnected(true);
			cleanup();
			fireTerminateEvent();
		}
	}

	/** 
	 * Cleans up the internal state of this debug
	 * target as a result of a session ending with a
	 * VM (as a result of a disconnect or termination of
	 * the VM).
	 * <p>
	 * All threads are removed from this target.
	 * This target is removed as a breakpoint listener,
	 * and all breakpoints are removed from this target.
	 * </p>
	 */
	protected void cleanup() {
		removeAllThreads();
		DebugPlugin plugin = DebugPlugin.getDefault();
		plugin.getBreakpointManager().removeBreakpointListener(this);
		plugin.getLaunchManager().removeLaunchListener(this);
		plugin.getBreakpointManager().removeBreakpointManagerListener(this);
        plugin.removeDebugEventListener(this);
		removeAllBreakpoints();
		fOutOfSynchTypes.clear();
		if (fEngines != null) {
			Iterator engines = fEngines.values().iterator();
			while (engines.hasNext()) {
				IAstEvaluationEngine engine = (IAstEvaluationEngine)engines.next();
				engine.dispose();
			}
			fEngines.clear();
		}
		fVirtualMachine= null;
		setThreadStartHandler(null);
		setEventDispatcher(null);
		setStepFilters(new String[0]);
	}

	/**
	 * Removes all threads from this target's collection
	 * of threads, firing a terminate event for each.
	 */
	protected void removeAllThreads() {
		Iterator itr= getThreadIterator();
		while (itr.hasNext()) {
			JDIThread child= (JDIThread) itr.next();
			child.terminated();
		}
		synchronized (fThreads) {
		    fThreads.clear();
		}
	}

	/**
	 * Removes all breakpoints from this target, such
	 * that each breakpoint can update its install
	 * count. This target's collection of breakpoints
	 * is cleared.
	 */
	protected void removeAllBreakpoints() {
		Iterator breakpoints= ((ArrayList)((ArrayList)getBreakpoints()).clone()).iterator();
		while (breakpoints.hasNext()) {
			JavaBreakpoint breakpoint= (JavaBreakpoint) breakpoints.next();
			try {
				breakpoint.removeFromTarget(this);
			} catch (CoreException e) {
				logError(e);
			}
		}
		getBreakpoints().clear();
	}
	
	/**
	 * Adds all the breakpoints in this target's collection
	 * to this debug target.
	 */
	protected void reinstallAllBreakpoints() {
		Iterator breakpoints= ((ArrayList)((ArrayList)getBreakpoints()).clone()).iterator();
		while (breakpoints.hasNext()) {
			JavaBreakpoint breakpoint= (JavaBreakpoint) breakpoints.next();
			try {
				breakpoint.addToTarget(this);
			} catch (CoreException e) {
				logError(e);
			}
		}
	}

	/**
	 * Returns VirtualMachine.classesByName(String),
	 * logging any JDI exceptions.
	 *
	 * @see com.sun.jdi.VirtualMachine
	 */
	public List jdiClassesByName(String className) {
		VirtualMachine vm = getVM();
		if (vm != null) {
			try {
				return vm.classesByName(className);
			} catch (VMDisconnectedException e) {
				if (!isAvailable()) {
					return Collections.EMPTY_LIST;
				}
				logError(e);
			} catch (RuntimeException e) {
				internalError(e);
			}
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @see IJavaDebugTarget#findVariable(String)
	 */
	public IJavaVariable findVariable(String varName) throws DebugException {
		IThread[] threads = getThreads();
		for (int i = 0; i < threads.length; i++) {
			IJavaThread thread = (IJavaThread)threads[i];
			IJavaVariable var = thread.findVariable(varName);
			if (var != null) {
				return var;
			}
		}
		return null;
	}
	
	/**
	 * @see IAdaptable#getAdapter(Class)
	 */
	public Object getAdapter(Class adapter) {
		if (adapter == IJavaDebugTarget.class) {
			return this;
		}
		return super.getAdapter(adapter);
	}
	
	/**
	 * The JDIDebugPlugin is shutting down.
	 * Shutdown the event dispatcher and do local
	 * cleanup.
	 */
	public void shutdown() {
		EventDispatcher dispatcher = ((JDIDebugTarget)getDebugTarget()).getEventDispatcher();
		if (dispatcher != null) {
			dispatcher.shutdown();
		}
		try {
			if (supportsTerminate()) {
				terminate();
			} else if (supportsDisconnect()) {
				disconnect();
			}
		} catch (DebugException e) {
			JDIDebugPlugin.log(e);
		}
		cleanup();
	}
	
	/**
	 * Returns the CRC-32 of the entire class file contents associated with
	 * given type, on the target VM, or <code>null</code> if the type is
	 * not loaded, or a CRC for the type is not known.
	 * 
	 * @param typeName fully qualified name of the type for which a
	 *    CRC is required. For example, "com.example.Example".
	 * @return 32 bit CRC, or <code>null</code>
	 * @exception DebugException if this method fails.  Reasons include:
	 * <ul>
	 * <li>Failure communicating with the VM.  The DebugException's
	 * status code contains the underlying exception responsible for
	 * the failure.</li>
	 * </ul>
	 */
	protected Integer getCRC(String typeName) throws DebugException {
		if (getVM() instanceof org.eclipse.jdi.hcr.VirtualMachine) {
			List classes = jdiClassesByName(typeName);
			if (!classes.isEmpty()) {
				ReferenceType type = (ReferenceType)classes.get(0);
				if (type instanceof org.eclipse.jdi.hcr.ReferenceType) {
					try {
						org.eclipse.jdi.hcr.ReferenceType rt = (org.eclipse.jdi.hcr.ReferenceType)type;
						if (rt.isVersionKnown()) {
							return new Integer(rt.getClassFileVersion());
						}
					} catch (RuntimeException e) {
						targetRequestFailed(MessageFormat.format(JDIDebugModelMessages.JDIDebugTarget_exception_retrieving_version_information, new String[] {e.toString(), type.name()}), e); 
						// execution will never reach this line, as
						// #targetRequestFailed will throw an exception						
						return null;
					}
				}
			}
		}
		return null;
	}

	/**
	 * @see IJavaDebugTarget#getJavaTypes(String)
	 */
	public IJavaType[] getJavaTypes(String name) throws DebugException {
		try {
			// get java.lang.Class
			VirtualMachine vm = getVM();
			if (vm == null) {
				requestFailed(JDIDebugModelMessages.JDIDebugTarget_Unable_to_retrieve_types___VM_disconnected__4, null); 
			}
			List classes = vm.classesByName(name);
			if (classes.size() == 0) {
				switch (name.charAt(0)) {
					case 'b':
						if (name.equals("boolean")) { //$NON-NLS-1$
							return new IJavaType[] {newValue(true).getJavaType()};
						} else if (name.equals("byte")) { //$NON-NLS-1$
							return new IJavaType[] {newValue((byte)1).getJavaType()};
						}
						break;
					case 'i':
						if (name.equals("int")) { //$NON-NLS-1$
							return new IJavaType[] {newValue(1).getJavaType()};
						}
						break;
					case 'l':
						if (name.equals("long")) { //$NON-NLS-1$
							return new IJavaType[] {newValue(1l).getJavaType()};
						}
						break;
					case 'c':
						if (name.equals("char")) { //$NON-NLS-1$
							return new IJavaType[] {newValue(' ').getJavaType()};
						}
						break;
					case 's':
						if (name.equals("short")) { //$NON-NLS-1$
							return new IJavaType[] {newValue((short)1).getJavaType()};
						}
						break;
					case 'f':
						if (name.equals("float")) { //$NON-NLS-1$
							return new IJavaType[] {newValue(1f).getJavaType()};
						}
						break;
					case 'd':
						if (name.equals("double")) { //$NON-NLS-1$
							return new IJavaType[] {newValue(1d).getJavaType()};
						}
						break;
				}
				return null;
			}
			IJavaType[] types = new IJavaType[classes.size()];
			for (int i = 0; i < types.length; i++) {
				types[i] = JDIType.createType(this, (Type)classes.get(i));
			}
			return types;
		} catch (RuntimeException e) {
			targetRequestFailed(MessageFormat.format("{0} occurred while retrieving class for name {1}", new String[]{e.toString(), name}), e); //$NON-NLS-1$
			// execution will not reach this line, as
			// #targetRequestFailed will throw an exception
			return null;
		}
	}
	
	/**
	 * @see IJavaDebugTarget#newValue(boolean)
	 */
	public IJavaValue newValue(boolean value) {
		VirtualMachine vm = getVM();
		if (vm != null) {
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}
	
	/**
	 * @see IJavaDebugTarget#newValue(byte)
	 */
	public IJavaValue newValue(byte value) {
		VirtualMachine vm = getVM();
		if (vm != null) {
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}

	/**
	 * @see IJavaDebugTarget#newValue(char)
	 */
	public IJavaValue newValue(char value) {
		VirtualMachine vm = getVM();
		if (vm != null) {
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}

	/**
	 * @see IJavaDebugTarget#newValue(double)
	 */
	public IJavaValue newValue(double value) {
		VirtualMachine vm = getVM();
		if (vm != null) {		
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}
	
	/**
	 * @see IJavaDebugTarget#newValue(float)
	 */
	public IJavaValue newValue(float value) {
		VirtualMachine vm = getVM();
		if (vm != null) {		
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}
						
	/**
	 * @see IJavaDebugTarget#newValue(int)
	 */
	public IJavaValue newValue(int value) {
		VirtualMachine vm = getVM();
		if (vm != null) {		
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}
	
	/**
	 * @see IJavaDebugTarget#newValue(long)
	 */
	public IJavaValue newValue(long value) {
		VirtualMachine vm = getVM();
		if (vm != null) {		
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}	
	
	/**
	 * @see IJavaDebugTarget#newValue(short)
	 */
	public IJavaValue newValue(short value) {
		VirtualMachine vm = getVM();
		if (vm != null) {		
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}
	
	/**
	 * @see IJavaDebugTarget#newValue(String)
	 */
	public IJavaValue newValue(String value) {
		VirtualMachine vm = getVM();
		if (vm != null) {		
			Value v = vm.mirrorOf(value);
			return JDIValue.createValue(this, v);
		}
		return null;
	}
		
	/**
	 * @see IJavaDebugTarget#nullValue()
	 */
	public IJavaValue nullValue() {
		return JDIValue.createValue(this, null);
	}
	
	/**
	 * @see IJavaDebugTarget#voidValue()
	 */
	public IJavaValue voidValue() {
		return new JDIVoidValue(this);
	}
	
	protected boolean isTerminating() {
		return fTerminating;
	}

	protected void setTerminating(boolean terminating) {
		fTerminating = terminating;
	}
		
	/**
	 * An event handler for thread start events. When a thread
	 * starts in the target VM, a model thread is created.
	 */
	class ThreadStartHandler implements IJDIEventListener {
		
		protected EventRequest fRequest;
		
		protected ThreadStartHandler() {
			createRequest();
		} 
		
		/**
		 * Creates and registers a request to handle all thread start
		 * events
		 */
		protected void createRequest() {
			EventRequestManager manager = getEventRequestManager();
			if (manager != null) {			
				try {
					EventRequest req= manager.createThreadStartRequest();
					req.setSuspendPolicy(EventRequest.SUSPEND_NONE);
					req.enable();
					addJDIEventListener(this, req);
					setRequest(req);
				} catch (RuntimeException e) {
					logError(e);
				}
			}
		}

		/**
		 * Creates a model thread for the underlying JDI thread
		 * and adds it to the collection of threads for this 
		 * debug target. As a side effect of creating the thread,
		 * a create event is fired for the model thread.
		 * The event is ignored if the underlying thread is already
		 * marked as collected.
		 * 
		 * @param event a thread start event
		 * @param target the target in which the thread started
		 * @return <code>true</code> - the thread should be resumed
		 */
		public boolean handleEvent(Event event, JDIDebugTarget target) {
			ThreadReference thread= ((ThreadStartEvent)event).thread();
			try {
				if (thread.isCollected()) {
					return false;
				}
			} catch (VMDisconnectedException exception) {
				return false;
			} catch (ObjectCollectedException e) {
				return false;
			} catch (TimeoutException e) {
				// continue - attempt to create the thread
			}
			JDIThread jdiThread= findThread(thread);
			if (jdiThread == null) {
				jdiThread = createThread(thread);
				if (jdiThread == null) {
					return false;
				}
			} else {
				jdiThread.disposeStackFrames();
				jdiThread.fireChangeEvent(DebugEvent.CONTENT);
			}
			return !jdiThread.isSuspended();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.debug.core.IJDIEventListener#wonSuspendVote(com.sun.jdi.event.Event, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
		 */
		public void wonSuspendVote(Event event, JDIDebugTarget target) {
			// do nothing
		}
		
		/**
		 * De-registers this event listener.
		 */
		protected void deleteRequest() {
			if (getRequest() != null) {
				removeJDIEventListener(this, getRequest());
				setRequest(null);
			}
		}
		
		protected EventRequest getRequest() {
			return fRequest;
		}

		protected void setRequest(EventRequest request) {
			fRequest = request;
		}
}
	
	/**
	 * An event handler for thread death events. When a thread
	 * dies in the target VM, its associated model thread is
	 * removed from the debug target.
	 */
	class ThreadDeathHandler implements IJDIEventListener {
		
		protected ThreadDeathHandler() {
			createRequest();
		}
		
		/**
		 * Creates and registers a request to listen to thread
		 * death events.
		 */
		protected void createRequest() {
			EventRequestManager manager = getEventRequestManager();
			if (manager != null) {
				try {
					EventRequest req= manager.createThreadDeathRequest();
					req.setSuspendPolicy(EventRequest.SUSPEND_NONE);
					req.enable();
					addJDIEventListener(this, req);	
				} catch (RuntimeException e) {
					logError(e);
				}					
			}
		}
				
		/**
		 * Locates the model thread associated with the underlying JDI thread
		 * that has terminated, and removes it from the collection of
		 * threads belonging to this debug target. A terminate event is
		 * fired for the model thread.
		 *
		 * @param event a thread death event
		 * @param target the target in which the thread died
		 * @return <code>true</code> - the thread should be resumed
		 */
		public boolean handleEvent(Event event, JDIDebugTarget target) {
			ThreadReference ref= ((ThreadDeathEvent)event).thread();
			JDIThread thread= findThread(ref);
			if (thread != null) {
				synchronized (fThreads) {
					fThreads.remove(thread);
				}
				thread.terminated();
			}
			return true;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.debug.core.IJDIEventListener#wonSuspendVote(com.sun.jdi.event.Event, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
		 */
		public void wonSuspendVote(Event event, JDIDebugTarget target) {
			// do nothing
		}
	
	}
	
	class CleanUpJob extends Job {

		/**
		 * Constructs a job to cleanup a hanging target.
		 */
		public CleanUpJob() {
			super(JDIDebugModelMessages.JDIDebugTarget_0);
			setSystem(true);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor)
		 */
		protected IStatus run(IProgressMonitor monitor) {
			if (isAvailable()) {
				if (fEventDispatcher != null) {
					fEventDispatcher.shutdown();
				}
				disconnected();
			}
			return Status.OK_STATUS;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#shouldRun()
		 */
		public boolean shouldRun() {
			return isAvailable();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.internal.jobs.InternalJob#shouldSchedule()
		 */
		public boolean shouldSchedule() {
			return isAvailable();
		}
		
		
	}
	
	protected ThreadStartHandler getThreadStartHandler() {
		return fThreadStartHandler;
	}

	protected void setThreadStartHandler(ThreadStartHandler threadStartHandler) {
		fThreadStartHandler = threadStartHandler;
	}
	
	/**
	 * Java debug targets do not support storage retrieval.
	 * 
	 * @see IMemoryBlockRetrieval#supportsStorageRetrieval()
	 */
	public boolean supportsStorageRetrieval() {
		return false;
	}

	/**
	 * @see IMemoryBlockRetrieval#getMemoryBlock(long, long)
	 */
	public IMemoryBlock getMemoryBlock(long startAddress, long length)
		throws DebugException {
			notSupported(JDIDebugModelMessages.JDIDebugTarget_does_not_support_storage_retrieval); 
			// this line will not be executed as #notSupported(String)
			// will throw an exception
			return null;
	}

	/**
	 * @see ILaunchListener#launchRemoved(ILaunch)
	 */
	public void launchRemoved(ILaunch launch) {
		if (!isAvailable()) {
			return;
		}
		if (launch.equals(getLaunch())) {
			// This target has been de-registered, but it hasn't successfully terminated.
			// Update internal state to reflect that it is disconnected
			disconnected();
		}
	}

	/**
	 * @see ILaunchListener#launchAdded(ILaunch)
	 */
	public void launchAdded(ILaunch launch) {
	}
	
	/**
	 * @see ILaunchListener#launchChanged(ILaunch)
	 */
	public void launchChanged(ILaunch launch) {
	}	

	/**
	 * Sets whether the VM should be resumed on startup.
	 * Has no effect if the VM is already running when
	 * this target is created.
	 * 
	 * @param resume whether the VM should be resumed on startup
	 */
	private synchronized void setResumeOnStartup(boolean resume) {
		fResumeOnStartup = resume;
	}
	
	/**
	 * Returns whether this VM should be resumed on startup.
	 * 
	 * @return whether this VM should be resumed on startup
	 */
	protected synchronized boolean isResumeOnStartup() {
		return fResumeOnStartup;
	}
	
	/**
	 * @see IJavaDebugTarget#getStepFilters()
	 */
	public String[] getStepFilters() {
		return fStepFilters;
	}

	/**
	 * @see IJavaDebugTarget#isFilterConstructors()
	 */
	public boolean isFilterConstructors() {
		return (fStepFilterMask & FILTER_CONSTRUCTORS) > 0;
	}

	/**
	 * @see IJavaDebugTarget#isFilterStaticInitializers()
	 */
	public boolean isFilterStaticInitializers() {
		return (fStepFilterMask & FILTER_STATIC_INITIALIZERS) > 0;
	}

	/**
	 * @see IJavaDebugTarget#isFilterSynthetics()
	 */
	public boolean isFilterSynthetics() {
		return (fStepFilterMask & FILTER_SYNTHETICS) > 0;
	}
	
	/**
	 * Returns whether steps that land in filtered location should
	 * proceed through to an un-filtered location or return.
	 * 
	 * @return whether steps that land in filtered location should
	 * proceed through to an un-filtered location or return
	 * @since 3.3
	 * TODO: make API once API freeze is over
	 */
	public boolean isStepThruFilters() {
		return (fStepFilterMask & STEP_THRU_FILTERS) > 0;
	}	

	/**
	 * @see IJavaDebugTarget#isStepFiltersEnabled()
	 */
	public boolean isStepFiltersEnabled() {
		return (fStepFilterMask & STEP_FILTERS_ENABLED) > 0;
	}

	/**
	 * @see IJavaDebugTarget#setFilterConstructors(boolean)
	 */
	public void setFilterConstructors(boolean filter) {
		if (filter) {
			fStepFilterMask = fStepFilterMask | FILTER_CONSTRUCTORS;
		} else {
			fStepFilterMask = fStepFilterMask & (FILTER_CONSTRUCTORS ^ XOR_MASK);
		}
	}

	/**
	 * @see IJavaDebugTarget#setFilterStaticInitializers(boolean)
	 */
	public void setFilterStaticInitializers(boolean filter) {
		if (filter) {
			fStepFilterMask = fStepFilterMask | FILTER_STATIC_INITIALIZERS;
		} else {
			fStepFilterMask = fStepFilterMask & (FILTER_STATIC_INITIALIZERS ^ XOR_MASK);
		}		
	}

	/**
	 * @see IJavaDebugTarget#setFilterSynthetics(boolean)
	 */
	public void setFilterSynthetics(boolean filter) {
		if (filter) {
			fStepFilterMask = fStepFilterMask | FILTER_SYNTHETICS;
		} else {
			fStepFilterMask = fStepFilterMask & (FILTER_SYNTHETICS ^ XOR_MASK);
		}				
	}
	
	/**
	 * Sets whether a step that lands in a filtered location should continue through
	 * to an un-filtered location, or return to where the step originated.
	 * 
	 * @param thru whether to step thru
	 * @since 3.3
	 * TODO: make API once API freeze is over
	 */
	public void setStepThruFilters(boolean thru) {
		if (thru) {
			fStepFilterMask = fStepFilterMask | STEP_THRU_FILTERS;
		} else {
			fStepFilterMask = fStepFilterMask & (STEP_THRU_FILTERS ^ XOR_MASK);
		}				
	}	

	/**
	 * @see IJavaDebugTarget#setStepFilters(String[])
	 */
	public void setStepFilters(String[] list) {
		fStepFilters = list;
	}

	/**
	 * @see IJavaDebugTarget#setStepFiltersEnabled(boolean)
	 */
	public void setStepFiltersEnabled(boolean enabled) {
		if (enabled) {
			fStepFilterMask = fStepFilterMask | STEP_FILTERS_ENABLED;
		} else {
			fStepFilterMask = fStepFilterMask & (STEP_FILTERS_ENABLED ^ XOR_MASK);
		}				
	}

	/**
	 * @see IDebugTarget#hasThreads()
	 */
	public boolean hasThreads() {
		return fThreads.size() > 0;
	}
	
	/**
	 * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
	 */
	public ILaunch getLaunch() {
		return fLaunch;
	}

	/**
	 * Sets the launch this target is contained in
	 * 
	 * @param launch the launch this target is contained in
	 */
	private void setLaunch(ILaunch launch) {
		fLaunch = launch;
	}
	
	/**
	 * Returns the number of suspend events that have occurred in this
	 * target.
	 * 
	 * @return the number of suspend events that have occurred in this
	 * target
	 */
	protected int getSuspendCount() {
		return fSuspendCount;
	} 
	
	/**
	 * Increments the suspend counter for this target based on the reason
	 * for the suspend event. The suspend count is not updated for
	 * implicit evaluations.
	 * 
	 * @param eventDetail the reason for the suspend event
	 */
	protected void incrementSuspendCount(int eventDetail) {
	    if (eventDetail != DebugEvent.EVALUATION_IMPLICIT) {
	        fSuspendCount++;
	    }
	}
	
	/**
	 * Returns an evaluation engine for the given project, creating
	 * one if necessary.
	 * 
	 * @param project java project
	 * @return evaluation engine
	 */
	public IAstEvaluationEngine getEvaluationEngine(IJavaProject project) {
		if (fEngines == null) {
			fEngines = new HashMap(2);
		}
		IAstEvaluationEngine engine = (IAstEvaluationEngine)fEngines.get(project);
		if (engine == null) {
			engine = EvaluationManager.newAstEvaluationEngine(project, this);
			fEngines.put(project, engine);
		}
		return engine;
	}
	
	/**
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#supportsMonitorInformation()
	 */
	public boolean supportsMonitorInformation() {
		if (!isAvailable()) {
			return false;
		}
		VirtualMachine vm = getVM();
		if (vm != null) {
			return vm.canGetCurrentContendedMonitor() && vm.canGetMonitorInfo() && vm.canGetOwnedMonitorInfo();
		}
		return false;
	}
	
	/**
	 * Sets whether or not this debug target is currently performing a hot code
	 * replace.
	 */
	public void setIsPerformingHotCodeReplace(boolean isPerformingHotCodeReplace) {
		fIsPerformingHotCodeReplace= isPerformingHotCodeReplace;
	}
	
	/**
	 * @see IJavaDebugTarget#isPerformingHotCodeReplace()
	 */
	public boolean isPerformingHotCodeReplace() {
		return fIsPerformingHotCodeReplace;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#supportsAccessWatchpoints()
	 */
	public boolean supportsAccessWatchpoints() {
		VirtualMachine vm = getVM();
		if (isAvailable() && vm != null) {
			return vm.canWatchFieldAccess();
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#supportsModificationWatchpoints()
	 */
	public boolean supportsModificationWatchpoints() {
		VirtualMachine vm = getVM();
		if (isAvailable() && vm != null) {
			return vm.canWatchFieldModification();
		}
		return false;
	}

	/**
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#setDefaultStratum()
	 */
	public void setDefaultStratum(String stratum) {
		VirtualMachine vm = getVM();
		if (vm != null) {
		    vm.setDefaultStratum(stratum);
		}
	}
	
	public String getDefaultStratum() {
		VirtualMachine vm = getVM();
		if (vm != null) {
		    return vm.getDefaultStratum();
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStepFilters#supportsStepFilters()
	 */
	public boolean supportsStepFilters() {
		return isAvailable();
	}

	/**
	 * When the breakpoint manager disables, remove all registered breakpoints
	 * requests from the VM. When it enables, reinstall them.
	 */
	public void breakpointManagerEnablementChanged(boolean enabled) {
		if (!isAvailable()) {
			return;
		}
		Iterator breakpoints= ((ArrayList)((ArrayList)getBreakpoints()).clone()).iterator();
		while (breakpoints.hasNext()) {
			JavaBreakpoint breakpoint= (JavaBreakpoint) breakpoints.next();
			try {
				if (enabled) {
					breakpoint.addToTarget(this);
				} else if (breakpoint.shouldSkipBreakpoint()) {
					breakpoint.removeFromTarget(this);
				}
			} catch (CoreException e) {
				logError(e);
			}
		}
	}

    /* (non-Javadoc)
     * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
     */
    public void handleDebugEvents(DebugEvent[] events) {
        if (events.length == 1) {
            DebugEvent event = events[0];
            if (event.getSource().equals(getProcess()) && event.getKind() == DebugEvent.TERMINATE) {
            	// schedule a job to clean up the target in case we never get a terminate/disconnect
            	// event from the VM
            	int timeout = getRequestTimeout();
            	if (timeout < 0) {
            		timeout = 3000;
            	}
            	new CleanUpJob().schedule(timeout);
            }
        }
    }
    
    /* (non-Javadoc)
     * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
     */
    public IDebugTarget getDebugTarget() {
        return this;
    }
    
    /**
     * Adds the given thread group to the list of known thread groups.  Also adds any parent thread groups
     * that have not already been added to the list.
     * 
     * @param group thread group to add
     */
    void addThreadGroup(ThreadGroupReference group) {
    	ThreadGroupReference currentGroup = group;
    	while(currentGroup != null){
	    	synchronized (fGroups) {
	    		if (findThreadGroup(currentGroup) == null) {
	    			JDIThreadGroup modelGroup = new JDIThreadGroup(this, currentGroup);
	        		fGroups.add(modelGroup);
	        		currentGroup = currentGroup.parent();
	        		// TODO: create event?
	    		} else {
	    			currentGroup = null;
	    		}
			}
    	}
    }
    
    JDIThreadGroup findThreadGroup(ThreadGroupReference group) {
    	synchronized (fGroups) {
    		Iterator groups = fGroups.iterator();
    		while (groups.hasNext()) {
    			JDIThreadGroup modelGroup = (JDIThreadGroup) groups.next();
    			if (modelGroup.getUnderlyingThreadGroup().equals(group)) {
    				return modelGroup;
    			}
    		}
    	}
    	return null;
    }

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#getThreadGroups()
	 */
	public IJavaThreadGroup[] getRootThreadGroups() throws DebugException {
		try {
			VirtualMachine vm = getVM();
			if (vm == null) {
				return new IJavaThreadGroup[0];
			}
			List groups = vm.topLevelThreadGroups();
			List modelGroups = new ArrayList(groups.size());
			Iterator iterator = groups.iterator();
			while (iterator.hasNext()) {
				ThreadGroupReference ref = (ThreadGroupReference) iterator.next();
				JDIThreadGroup group = findThreadGroup(ref);
				if (group != null) {
					modelGroups.add(group);
				}
			}
			return (IJavaThreadGroup[]) modelGroups.toArray(new IJavaThreadGroup[modelGroups.size()]);
		} catch (RuntimeException e) {
			targetRequestFailed(JDIDebugModelMessages.JDIDebugTarget_1, e);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#getAllThreadGroups()
	 */
	public IJavaThreadGroup[] getAllThreadGroups() throws DebugException {
		synchronized (fGroups) {
			return (IJavaThreadGroup[]) fGroups.toArray(new IJavaThreadGroup[fGroups.size()]);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#supportsInstanceRetrieval()
	 */
	public boolean supportsInstanceRetrieval() {
		VirtualMachine vm = getVM();
		if (vm != null) {
			return vm.canGetInstanceInfo();
		}
		return false;
	}
	
	/**
	 * Sends a JDWP command to the back end and returns the JDWP reply packet as bytes.
	 * This method creates an appropriate command header and packet id, before sending
	 * to the back end.
	 * 
	 * @param commandSet command set identifier as defined by JDWP
	 * @param commandId command identifier as defined by JDWP
	 * @param data any bytes required for the command that follow the command header
	 * 	or <code>null</code> for commands that have no data
	 * @return raw reply packet as bytes defined by JDWP
	 * @exception IOException if an error occurs sending the packet or receiving the reply
	 * @since 3.3
	 */
	public byte[] sendJDWPCommand(byte commandSet, byte commandId, byte[] data) throws IOException {
		int command = (256 * commandSet) + commandId;
		JdwpReplyPacket reply = ((VirtualMachineImpl)getVM()).requestVM(command, data);
		return reply.getPacketAsBytes();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#supportsForceReturn()
	 */
	public boolean supportsForceReturn() {
		VirtualMachine machine = getVM();
		if(machine == null) {
			return false;
		}
		return machine.canForceEarlyReturn();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#supportsSelectiveGarbageCollection()
	 */
	public boolean supportsSelectiveGarbageCollection() {
		return fSupportsDisableGC;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#getVMName()
	 */
	public String getVMName() throws DebugException {
		VirtualMachine vm = getVM();
		if (vm == null) {
			requestFailed(JDIDebugModelMessages.JDIDebugTarget_2, new VMDisconnectedException()); 
		}
		try {
			return vm.name();
		} catch (RuntimeException e) {
			targetRequestFailed(JDIDebugModelMessages.JDIDebugTarget_2, e); 
			// execution will not reach this line, as 
			// #targetRequestFailed will throw an exception				
			return null;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaDebugTarget#getVersion()
	 */
	public String getVersion() throws DebugException {
		VirtualMachine vm = getVM();
		if (vm == null) {
			requestFailed(JDIDebugModelMessages.JDIDebugTarget_4, new VMDisconnectedException()); 
		}
		try {
			return vm.version();
		} catch (RuntimeException e) {
			targetRequestFailed(JDIDebugModelMessages.JDIDebugTarget_4, e); 
			// execution will not reach this line, as 
			// #targetRequestFailed will throw an exception				
			return null;
		}
	}	
}
