/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Samrat Dhillon samrat.dhillon@gmail.com - Bug 384458 - debug shows value of variable in another scope 
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.core.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IRegisterGroup;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IStep;
import org.eclipse.debug.core.model.ISuspendResume;
import org.eclipse.debug.core.model.ITerminate;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;

import org.eclipse.jdi.internal.ValueImpl;
import org.eclipse.jdi.internal.VirtualMachineImpl;

import org.eclipse.jdt.core.Signature;

import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaModifiers;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;

import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIReturnValueVariable;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
import com.sun.jdi.NativeMethodException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.StackFrame;
import com.sun.jdi.Type;
import com.sun.jdi.VirtualMachine;

/**
 * Proxy to a stack frame on the target.
 */

public class JDIStackFrame extends JDIDebugElement implements IJavaStackFrame {

	/**
	 * This frame's depth in the call stack (0 == bottom of stack). A new frame
	 * is indicated by -2. An invalid frame is indicated by -1.
	 */
	private int fDepth = -2;

	/**
	 * Underlying JDI stack frame.
	 */
	private StackFrame fStackFrame;

	/**
	 * Containing thread.
	 */
	private JDIThread fThread;
	/**
	 * Visible variables.
	 */
	private List<IJavaVariable> fVariables;

	/**
	 * The underlying Object associated with this stack frame. Cached lazily on
	 * first access.
	 */
	private ObjectReference fThisObject;

	/**
	 * The name of the type of the object that received the method call
	 * associated with this stack frame. Cached lazily on first access.
	 */
	private String fReceivingTypeName;
	/**
	 * Whether the variables need refreshing
	 */
	private boolean fRefreshVariables = true;
	/**
	 * Whether this stack frame has been marked as out of synch. If set to
	 * <code>true</code> this stack frame will stop dynamically calculating its
	 * out of synch state.
	 */
	private boolean fIsOutOfSynch = false;

	/**
	 * Whether local variable information was available
	 */
	private boolean fLocalsAvailable = true;

	/**
	 * Location of this stack frame
	 */
	private Location fLocation;

	/**
	 * Whether the current stack frame is the top of the stack
	 */
	private boolean fIsTop;

	/**
	 * Creates a new stack frame in the given thread.
	 * 
	 * @param thread
	 *            The parent JDI thread
	 * @param frame
	 *            underlying frame
	 * @param depth
	 *            depth on the stack (0 is bottom)
	 */
	public JDIStackFrame(JDIThread thread, StackFrame frame, int depth) {
		super((JDIDebugTarget) thread.getDebugTarget());
		setThread(thread);
		bind(frame, depth);
	}

	/**
	 * Binds this frame to the given underlying frame on the target VM or
	 * returns a new frame representing the given frame. A frame can only be
	 * re-bound to an underlying frame if it refers to the same depth on the
	 * stack in the same method.
	 * 
	 * @param frame
	 *            underlying frame, or <code>null</code>
	 * @param depth
	 *            depth in the call stack, or -1 to indicate the frame should
	 *            become invalid
	 * @param return a frame to refer to the given frame or <code>null</code>
	 */
	protected JDIStackFrame bind(StackFrame frame, int depth) {
		synchronized (fThread) {
			if (fDepth == -2) {
				// first initialization
				fStackFrame = frame;
				fDepth = depth;
				fLocation = frame.location();
				return this;
			} else if (depth == -1) {
				// mark as invalid
				fDepth = -1;
				fStackFrame = null;
				fIsTop = false;
				return null;
			} else if (fDepth == depth) {
				Location location = frame.location();
				Method method = location.method();
				if (method.equals(fLocation.method())) {
					try {
						if (method.declaringType().defaultStratum()
								.equals("Java") || //$NON-NLS-1$
								equals(getSourceName(location),
										getSourceName(fLocation))) {
							// TODO: what about receiving type being the same?
							fStackFrame = frame;
							fLocation = location;
							clearCachedData();
							return this;
						}
					} catch (DebugException e) {
					}
				}
			}
			// invalidate this frame
			bind(null, -1);
			// return a new frame
			return new JDIStackFrame(fThread, frame, depth);
		}

	}

	/**
	 * @see IStackFrame#getThread()
	 */
	@Override
	public IThread getThread() {
		return fThread;
	}

	/**
	 * @see ISuspendResume#canResume()
	 */
	@Override
	public boolean canResume() {
		return getThread().canResume();
	}

	/**
	 * @see ISuspendResume#canSuspend()
	 */
	@Override
	public boolean canSuspend() {
		return getThread().canSuspend();
	}

	/**
	 * @see IStep#canStepInto()
	 */
	@Override
	public boolean canStepInto() {
		try {
			return exists() && isTopStackFrame() && !isObsolete()
					&& getThread().canStepInto();
		} catch (DebugException e) {
			logError(e);
			return false;
		}
	}

	/**
	 * @see IStep#canStepOver()
	 */
	@Override
	public boolean canStepOver() {
		return exists() && !isObsolete() && getThread().canStepOver();
	}

	/**
	 * @see IStep#canStepReturn()
	 */
	@Override
	public boolean canStepReturn() {
		try {
			if (!exists() || isObsolete() || !getThread().canStepReturn()) {
				return false;
			}
			List<IJavaStackFrame> frames = ((JDIThread) getThread())
					.computeStackFrames();
			if (frames != null && !frames.isEmpty()) {
				boolean bottomFrame = this
						.equals(frames.get(frames.size() - 1));
				boolean aboveObsoleteFrame = false;
				if (!bottomFrame) {
					int index = frames.indexOf(this);
					if (index < frames.size() - 1
							&& ((JDIStackFrame) frames.get(index + 1))
									.isObsolete()) {
						aboveObsoleteFrame = true;
					}
				}
				return !bottomFrame && !aboveObsoleteFrame;
			}
		} catch (DebugException e) {
			logError(e);
		}
		return false;
	}

	/**
	 * Returns the underlying method associated with this stack frame,
	 * retrieving the method is necessary.
	 */
	public Method getUnderlyingMethod() {
		synchronized (fThread) {
			return fLocation.method();
		}
	}

	/**
	 * @see IStackFrame#getVariables()
	 */
	@Override
	public IVariable[] getVariables() throws DebugException {
		List<IJavaVariable> list = getVariables0();
		return list.toArray(new IVariable[list.size()]);
	}

	protected List<IJavaVariable> getVariables0() throws DebugException {
		synchronized (fThread) {
			if (fVariables == null) {

				// throw exception if native method, so variable view will
				// update
				// with information message
				if (isNative()) {
					requestFailed(
							JDIDebugModelMessages.JDIStackFrame_Variable_information_unavailable_for_native_methods,
							null);
				}

				Method method = getUnderlyingMethod();
				fVariables = new ArrayList<IJavaVariable>();
				// #isStatic() does not claim to throw any exceptions - so it is
				// not try/catch coded
				if (method.isStatic()) {
					// add statics
					List<Field> allFields = null;
					ReferenceType declaringType = method.declaringType();
					try {
						allFields = declaringType.allFields();
					} catch (RuntimeException e) {
						targetRequestFailed(
								MessageFormat.format(
										JDIDebugModelMessages.JDIStackFrame_exception_retrieving_fields,
										e.toString()), e);
						// execution will not reach this line, as
						// #targetRequestFailed will throw an exception
						return Collections.EMPTY_LIST;
					}
					if (allFields != null) {
						Iterator<Field> fields = allFields.iterator();
						while (fields.hasNext()) {
							Field field = fields.next();
							if (field.isStatic()) {
								fVariables.add(new JDIFieldVariable(
										(JDIDebugTarget) getDebugTarget(),
										field, declaringType));
							}
						}
						Collections.sort(fVariables,
								new Comparator<IJavaVariable>() {
									@Override
									public int compare(IJavaVariable a, IJavaVariable b) {
										JDIFieldVariable v1 = (JDIFieldVariable) a;
										JDIFieldVariable v2 = (JDIFieldVariable) b;
										try {
											return v1.getName()
													.compareToIgnoreCase(
															v2.getName());
										} catch (DebugException de) {
											logError(de);
											return -1;
										}
									}
								});
					}
				} else {
					// add "this"
					ObjectReference t = getUnderlyingThisObject();
					if (t != null) {
						fVariables.add(new JDIThisVariable(
								(JDIDebugTarget) getDebugTarget(), t));
					}
				}
				addStepReturnValue(fVariables);
				// add locals
				Iterator<LocalVariable> variables = getUnderlyingVisibleVariables()
						.iterator();
				while (variables.hasNext()) {
					LocalVariable var = variables.next();
					fVariables.add(new JDILocalVariable(this, var));
				}
			} else if (fRefreshVariables) {
				updateVariables();
			}
			fRefreshVariables = false;
			return fVariables;
		}
	}

	/**
	 * If there is a return value from a "step return" that belongs to this frame, insert it as first element
	 *
	 * @param variables
	 */
	private void addStepReturnValue(List<IJavaVariable> variables) {
		if (fIsTop) {
			StepResult stepResult = fThread.fStepResult;
			if (stepResult != null) {
				if (stepResult.fIsReturnValue) {
					if (fDepth + 1 != stepResult.fTargetFrameCount) {
						// can happen e.g., because of checkPackageAccess/System.getSecurityManager()
						return;
					}
					String name = MessageFormat.format(JDIDebugModelMessages.JDIStackFrame_ReturnValue, stepResult.fMethod.name());
					variables.add(0, new JDIReturnValueVariable(name, JDIValue.createValue(getJavaDebugTarget(), stepResult.fValue)));
				} else {
					if (fDepth + 1 > stepResult.fTargetFrameCount) {
						// don't know if this really can happen, but other jvm suprises were not expected either
						return;
					}
					String name = MessageFormat.format(JDIDebugModelMessages.JDIStackFrame_ExceptionThrown, stepResult.fMethod.name());
					variables.add(0, new JDIReturnValueVariable(name, JDIValue.createValue(getJavaDebugTarget(), stepResult.fValue)));
				}
			}
		}
	}

	/**
	 * @see IStackFrame#getName()
	 */
	@Override
	public String getName() throws DebugException {
		return getMethodName();
	}

	/**
	 * @see IJavaStackFrame#getArgumentTypeNames()
	 */
	@Override
	public List<String> getArgumentTypeNames() throws DebugException {
		try {
			Method underlyingMethod = getUnderlyingMethod();
			String genericSignature = underlyingMethod.genericSignature();
			if (genericSignature == null) {
				// no generic signature
				return underlyingMethod.argumentTypeNames();
			}
			// generic signature
			String[] parameterTypes = Signature
					.getParameterTypes(genericSignature);
			List<String> argumentTypeNames = new ArrayList<String>();
			for (String parameterType : parameterTypes) {
				argumentTypeNames.add(Signature.toString(parameterType)
						.replace('/', '.'));
			}
			return argumentTypeNames;
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIStackFrame_exception_retrieving_argument_type_names,
							e.toString()), e);
			// execution will never reach this line, as
			// #targetRequestFailed will throw an exception
			return null;
		}
	}

	/**
	 * @see IStackFrame#getLineNumber()
	 */
	@Override
	public int getLineNumber() throws DebugException {
		synchronized (fThread) {
			try {
				return fLocation.lineNumber();
			} catch (RuntimeException e) {
				if (getThread().isSuspended()) {
					targetRequestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIStackFrame_exception_retrieving_line_number,
									e.toString()), e);
				}
			}
		}
		return -1;
	}

	/**
	 * @see IStep#isStepping()
	 */
	@Override
	public boolean isStepping() {
		return getThread().isStepping();
	}

	/**
	 * @see ISuspendResume#isSuspended()
	 */
	@Override
	public boolean isSuspended() {
		return getThread().isSuspended();
	}

	/**
	 * @see ISuspendResume#resume()
	 */
	@Override
	public void resume() throws DebugException {
		getThread().resume();
	}

	/**
	 * @see IStep#stepInto()
	 */
	@Override
	public void stepInto() throws DebugException {
		if (!canStepInto()) {
			return;
		}
		getThread().stepInto();
	}

	/**
	 * @see IStep#stepOver()
	 */
	@Override
	public void stepOver() throws DebugException {
		if (!canStepOver()) {
			return;
		}
		if (isTopStackFrame()) {
			getThread().stepOver();
		} else {
			((JDIThread) getThread()).stepToFrame(this);
		}
	}

	/**
	 * @see IStep#stepReturn()
	 */
	@Override
	public void stepReturn() throws DebugException {
		if (!canStepReturn()) {
			return;
		}
		if (isTopStackFrame()) {
			getThread().stepReturn();
		} else {
			List<IJavaStackFrame> frames = ((JDIThread) getThread())
					.computeStackFrames();
			int index = frames.indexOf(this);
			if (index >= 0 && index < frames.size() - 1) {
				IStackFrame nextFrame = frames.get(index + 1);
				((JDIThread) getThread()).stepToFrame(nextFrame);
			}
		}
	}

	/**
	 * @see ISuspendResume#suspend()
	 */
	@Override
	public void suspend() throws DebugException {
		getThread().suspend();
	}

	/**
	 * Incrementally updates this stack frames variables.
	 * 
	 * @see JDIDebugElement#targetRequestFailed(String, RuntimeException)
	 */
	protected void updateVariables() throws DebugException {
		if (fVariables == null) {
			return;
		}

		// remove old return value first, so the "this" updating logic below works
		if (!fVariables.isEmpty() && fVariables.get(0) instanceof JDIReturnValueVariable) {
			fVariables.remove(0);
		}

		Method method = getUnderlyingMethod();
		int index = 0;
		if (!method.isStatic()) {
			// update "this"
			ObjectReference thisObject;
			thisObject = getUnderlyingThisObject();
			JDIThisVariable oldThisObject = null;
			if (!fVariables.isEmpty()
					&& fVariables.get(0) instanceof JDIThisVariable) {
				oldThisObject = (JDIThisVariable) fVariables.get(0);
			}
			if (thisObject == null && oldThisObject != null) {
				// removal of 'this'
				fVariables.remove(0);
				index = 0;
			} else {
				if (oldThisObject == null && thisObject != null) {
					// creation of 'this'
					oldThisObject = new JDIThisVariable(
							(JDIDebugTarget) getDebugTarget(), thisObject);
					fVariables.add(0, oldThisObject);
					index = 1;
				} else {
					if (oldThisObject != null) {
						// 'this' still exists, replace with new 'this' if a
						// different receiver
						if (!oldThisObject.retrieveValue().equals(thisObject)) {
							fVariables.remove(0);
							fVariables.add(0, new JDIThisVariable(
									(JDIDebugTarget) getDebugTarget(),
									thisObject));
						}
						index = 1;
					}
				}
			}
		}

		List<LocalVariable> locals = null;
		try {
			locals = getUnderlyingStackFrame().visibleVariables();
		} catch (AbsentInformationException e) {
			locals = Collections.EMPTY_LIST;
		} catch (NativeMethodException e) {
			locals = Collections.EMPTY_LIST;
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIStackFrame_exception_retrieving_visible_variables,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will throw an exception
			return;
		}
		int localIndex = -1;
		while (index < fVariables.size()) {
			Object var = fVariables.get(index);
			if (var instanceof JDILocalVariable) {
				JDILocalVariable local = (JDILocalVariable) fVariables
						.get(index);
				localIndex = locals.indexOf(local.getLocal());
				if (localIndex >= 0) {
					// update variable with new underling JDI LocalVariable
					local.setLocal(locals.get(localIndex));
					locals.remove(localIndex);
					index++;
				} else {
					// remove variable
					fVariables.remove(index);
				}
			} else {
				// field variable of a static frame
				index++;
			}
		}

		// add any new locals
		Iterator<LocalVariable> newOnes = locals.iterator();
		while (newOnes.hasNext()) {
			JDILocalVariable local = new JDILocalVariable(this, newOnes.next());
			fVariables.add(local);
		}

		addStepReturnValue(fVariables);
	}

	/**
	 * @see org.eclipse.debug.core.model.IDropToFrame#canDropToFrame()
	 */
	@Override
	public boolean canDropToFrame() {
		return supportsDropToFrame();
	}

	/**
	 * @see IJavaStackFrame#supportsDropToFrame()
	 */
	@Override
	public boolean supportsDropToFrame() {
		JDIThread thread = (JDIThread) getThread();
		JDIDebugTarget target = (JDIDebugTarget) thread.getDebugTarget();
		try {
			if (!target.isAvailable() || !thread.isSuspended()
					|| thread.isTerminated() || thread.isInvokingMethod()) {
				return false;
			}
			boolean j9Support = false;
			boolean jdkSupport = target.canPopFrames();
			VirtualMachine vm = getVM();
			if (vm == null) {
				return false;
			}
			try {
				j9Support = (thread.getUnderlyingThread() instanceof org.eclipse.jdi.hcr.ThreadReference)
						&& ((org.eclipse.jdi.hcr.VirtualMachine) vm)
								.canDoReturn();
			} catch (UnsupportedOperationException uoe) {
				j9Support = false;
			}

			if (jdkSupport || j9Support) {
				// Also ensure that this frame and no frames above this
				// frame are native. Unable to pop native stack frames.
				List<IJavaStackFrame> frames = thread.computeStackFrames();
				if (jdkSupport) {
					// JDK 1.4 VMs are currently unable to pop the bottom
					// stack frame.
					if ((frames.size() > 0)
							&& frames.get(frames.size() - 1) == this) {
						return false;
					}
				}
				int index = 0;
				JDIStackFrame frame = null;
				while (index < frames.size()) {
					frame = (JDIStackFrame) frames.get(index);
					index++;
					if (frame.isNative()) {
						return false;
					}
					if (frame.equals(this)) {
						if (jdkSupport) {
							// JDK 1.4 VMs are currently unable to pop the
							// frame directly above a native frame
							if (index < frames.size()
									&& ((JDIStackFrame) frames.get(index))
											.isNative()) {
								return false;
							}
						}
						return true;
					}
				}
			}
			return false;
		} catch (DebugException e) {
			if (e.getStatus().getException() instanceof IncompatibleThreadStateException
					|| e.getStatus().getCode() == IJavaThread.ERR_THREAD_NOT_SUSPENDED) {
				// if the thread has since resumed, drop is not supported
				return false;
			}
			logError(e);
		} catch (UnsupportedOperationException e) {
			// drop to frame not supported - this is an expected
			// exception for VMs that do not support drop to frame
			return false;
		} catch (RuntimeException e) {
			internalError(e);
		}
		return false;
	}

	/**
	 * @see IJavaStackFrame#dropToFrame()
	 */
	@Override
	public void dropToFrame() throws DebugException {
		if (supportsDropToFrame()) {
			((JDIThread) getThread()).dropToFrame(this);
		} else {
			notSupported(JDIDebugModelMessages.JDIStackFrame_Drop_to_frame_not_supported);
		}
	}

	public void popFrame() throws DebugException {
		if (supportsDropToFrame()) {
			((JDIThread) getThread()).popFrame(this);
		} else {
			notSupported(JDIDebugModelMessages.JDIStackFrame_pop_frame_not_supported);
		}
	}

	/**
	 * @see IJavaStackFrame#findVariable(String)
	 */
	@Override
	public IJavaVariable findVariable(String varName) throws DebugException {
		if (isNative()) {
			return null;
		}
		IVariable[] variables = getVariables();
		List<IJavaVariable> possibleMatches = new ArrayList<IJavaVariable>();
		IJavaVariable thisVariable = null;
		for (IVariable variable : variables) {
			IJavaVariable var = (IJavaVariable) variable;
			if (var.getName().equals(varName)) {
				possibleMatches.add(var);
			}
			if (var instanceof JDIThisVariable) {
				// save for later - check for instance and static variables
				thisVariable = var;
			}
		}
		for(IJavaVariable variable: possibleMatches){
			// Local Variable has more preference than Field Variable
			if(variable instanceof JDILocalVariable){
				return variable;
			}
		}
		if(possibleMatches.size() > 0) {
			return possibleMatches.get(0);
		}

		if (thisVariable != null) {
			IVariable[] thisChildren = thisVariable.getValue().getVariables();
			for (IVariable element : thisChildren) {
				IJavaVariable var = (IJavaVariable) element;
				if (var.getName().equals(varName)) {
					return var;
				}
			}
		}
		return null;
	}

	/**
	 * Retrieves visible variables in this stack frame handling any exceptions.
	 * Returns an empty list if there are no variables.
	 * 
	 * @see JDIDebugElement#targetRequestFailed(String, RuntimeException)
	 */
	protected List<LocalVariable> getUnderlyingVisibleVariables() throws DebugException {
		synchronized (fThread) {
			List<LocalVariable> variables = Collections.EMPTY_LIST;
			try {
				variables = getUnderlyingStackFrame().visibleVariables();
			} catch (AbsentInformationException e) {
				setLocalsAvailable(false);
			} catch (NativeMethodException e) {
				setLocalsAvailable(false);
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIStackFrame_exception_retrieving_visible_variables_2,
								e.toString()), e);
			}
			return variables;
		}
	}

	/**
	 * Retrieves 'this' from the underlying stack frame. Returns
	 * <code>null</code> for static stack frames.
	 * 
	 * @see JDIDebugElement#targetRequestFailed(String, RuntimeException)
	 */
	protected ObjectReference getUnderlyingThisObject() throws DebugException {
		synchronized (fThread) {
			if ((fStackFrame == null || fThisObject == null) && !isStatic()) {
				try {
					fThisObject = getUnderlyingStackFrame().thisObject();
				} catch (RuntimeException e) {
					targetRequestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIStackFrame_exception_retrieving_this,
									e.toString()), e);
					// execution will not reach this line, as
					// #targetRequestFailed will throw an exception
					return null;
				}
			}
			return fThisObject;
		}
	}

	/**
	 * @see IAdaptable#getAdapter(Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (adapter == IJavaStackFrame.class || adapter == IJavaModifiers.class) {
			return (T) this;
		}
		return super.getAdapter(adapter);
	}

	/**
	 * @see IJavaStackFrame#getSignature()
	 */
	@Override
	public String getSignature() throws DebugException {
		try {
			return getUnderlyingMethod().signature();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIStackFrame_exception_retrieving_method_signature,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will throw an exception
			return null;
		}
	}

	/**
	 * @see IJavaStackFrame#getDeclaringTypeName()
	 */
	@Override
	public String getDeclaringTypeName() throws DebugException {
		synchronized (fThread) {
			try {
				if (isObsolete()) {
					return JDIDebugModelMessages.JDIStackFrame__unknown_declaring_type__1;
				}
				return JDIReferenceType.getGenericName(getUnderlyingMethod()
						.declaringType());
			} catch (RuntimeException e) {
				if (getThread().isSuspended()) {
					targetRequestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIStackFrame_exception_retrieving_declaring_type,
									e.toString()), e);
				}
				return JDIDebugModelMessages.JDIStackFrame__unknown_declaring_type__1;
			}
		}
	}

	/**
	 * @see IJavaStackFrame#getReceivingTypeName()
	 */
	@Override
	public String getReceivingTypeName() throws DebugException {
		if (fStackFrame == null || fReceivingTypeName == null) {
			try {
				if (isObsolete()) {
					fReceivingTypeName = JDIDebugModelMessages.JDIStackFrame__unknown_receiving_type__2;
				} else {
					ObjectReference thisObject = getUnderlyingThisObject();
					if (thisObject == null) {
						fReceivingTypeName = getDeclaringTypeName();
					} else {
						fReceivingTypeName = JDIReferenceType
								.getGenericName(thisObject.referenceType());
					}
				}
			} catch (RuntimeException e) {
				if (getThread().isSuspended()) {
					targetRequestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIStackFrame_exception_retrieving_receiving_type,
									e.toString()), e);
				}
				return JDIDebugModelMessages.JDIStackFrame__unknown_receiving_type__2;
			}
		}
		return fReceivingTypeName;
	}

	/**
	 * @see IJavaStackFrame#getMethodName()
	 */
	@Override
	public String getMethodName() throws DebugException {
		try {
			return getUnderlyingMethod().name();
		} catch (RuntimeException e) {
			if (getThread().isSuspended()) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIStackFrame_exception_retrieving_method_name,
								e.toString()), e);
			}
			return JDIDebugModelMessages.JDIStackFrame__unknown_method__1;
		}
	}

	/**
	 * @see IJavaStackFrame#isNative()
	 */
	@Override
	public boolean isNative() throws DebugException {
		return getUnderlyingMethod().isNative();
	}

	/**
	 * @see IJavaStackFrame#isConstructor()
	 */
	@Override
	public boolean isConstructor() throws DebugException {
		return getUnderlyingMethod().isConstructor();
	}

	/**
	 * @see IJavaStackFrame#isStaticInitializer()
	 */
	@Override
	public boolean isStaticInitializer() throws DebugException {
		return getUnderlyingMethod().isStaticInitializer();
	}

	/**
	 * @see IJavaModifiers#isFinal()
	 */
	@Override
	public boolean isFinal() throws DebugException {
		return getUnderlyingMethod().isFinal();
	}

	/**
	 * @see IJavaStackFrame#isSynchronized()
	 */
	@Override
	public boolean isSynchronized() throws DebugException {
		return getUnderlyingMethod().isSynchronized();
	}

	/**
	 * @see IJavaModifiers#isSynthetic()
	 */
	@Override
	public boolean isSynthetic() throws DebugException {
		return getUnderlyingMethod().isSynthetic();
	}

	/**
	 * @see IJavaModifiers#isPublic()
	 */
	@Override
	public boolean isPublic() throws DebugException {
		return getUnderlyingMethod().isPublic();
	}

	/**
	 * @see IJavaModifiers#isPrivate()
	 */
	@Override
	public boolean isPrivate() throws DebugException {
		return getUnderlyingMethod().isPrivate();
	}

	/**
	 * @see IJavaModifiers#isProtected()
	 */
	@Override
	public boolean isProtected() throws DebugException {
		return getUnderlyingMethod().isProtected();
	}

	/**
	 * @see IJavaModifiers#isPackagePrivate()
	 */
	@Override
	public boolean isPackagePrivate() throws DebugException {
		return getUnderlyingMethod().isPackagePrivate();
	}

	/**
	 * @see IJavaModifiers#isStatic()
	 */
	@Override
	public boolean isStatic() throws DebugException {
		return getUnderlyingMethod().isStatic();
	}

	/**
	 * @see IJavaStackFrame#getSourceName()
	 */
	@Override
	public String getSourceName() throws DebugException {
		synchronized (fThread) {
			return getSourceName(fLocation);
		}
	}

	/**
	 * Returns the source from the default stratum of the given location or
	 * <code>null</code> if not available (missing attribute).
	 */
	private String getSourceName(Location location) throws DebugException {
		try {
			return location.sourceName();
		} catch (AbsentInformationException e) {
			return null;
		} catch (NativeMethodException e) {
			return null;
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIStackFrame_exception_retrieving_source_name,
							e.toString()), e);
		}
		return null;
	}

	private boolean equals(Object o1, Object o2) {
		if (o1 == null) {
			return o2 == null;
		}
		return o1.equals(o2);
	}

	protected boolean isTopStackFrame() throws DebugException {
		IStackFrame tos = getThread().getTopStackFrame();
		return tos != null && tos.equals(this);
	}

	/**
	 * Sets this stack frame to be out of synch. Note that passing
	 * <code>true</code> to this method marks this stack frame as out of synch
	 * permanently (statically).
	 */
	public void setOutOfSynch(boolean outOfSynch) {
		fIsOutOfSynch = outOfSynch;
	}

	/**
	 * @see IJavaStackFrame#isOutOfSynch()
	 */
	@Override
	public boolean isOutOfSynch() throws DebugException {
		if (fIsOutOfSynch) {
			return true;
		}
		// if this frame's thread is not suspended, the out-of-synch info cannot
		// change until it suspends again
		if (getThread().isSuspended()) {
			JDIDebugTarget target = (JDIDebugTarget) getDebugTarget();
			if (target.hasHCROccurred()
					&& target.isOutOfSynch(getUnderlyingMethod()
							.declaringType().name())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @see IJavaStackFrame#isObsolete()
	 */
	@Override
	public boolean isObsolete() {
		if (!JDIDebugPlugin.isJdiVersionGreaterThanOrEqual(new int[] { 1, 4 })
				|| !((JDIDebugTarget) getDebugTarget()).hasHCROccurred()) {
			// If no hot code replace has occurred, this frame
			// cannot be obsolete.
			return false;
		}
		// if this frame's thread is not suspended, the obsolete status cannot
		// change until it suspends again
		synchronized (fThread) {
			if (getThread().isSuspended()) {
				return getUnderlyingMethod().isObsolete();
			}
			return false;
		}
	}

	protected boolean exists() {
		synchronized (fThread) {
			return fDepth != -1;
		}
	}

	/**
	 * @see ITerminate#canTerminate()
	 */
	@Override
	public boolean canTerminate() {
		return exists() && getThread().canTerminate()
				|| getDebugTarget().canTerminate();
	}

	/**
	 * @see ITerminate#isTerminated()
	 */
	@Override
	public boolean isTerminated() {
		return getThread().isTerminated();
	}

	/**
	 * @see ITerminate#terminate()
	 */
	@Override
	public void terminate() throws DebugException {
		if (getThread().canTerminate()) {
			getThread().terminate();
		} else {
			getDebugTarget().terminate();
		}
	}

	/**
	 * Returns this stack frame's underlying JDI frame.
	 * 
	 * @exception DebugException
	 *                if this stack frame does not currently have an underlying
	 *                frame (is in an interim state where this frame's thread
	 *                has been resumed, and is not yet suspended).
	 */
	protected StackFrame getUnderlyingStackFrame() throws DebugException {
		synchronized (fThread) {
			if (fStackFrame == null) {
				if (fDepth == -1) {
					throw new DebugException(new Status(IStatus.ERROR,
							JDIDebugPlugin.getUniqueIdentifier(),
							IJavaStackFrame.ERR_INVALID_STACK_FRAME,
							JDIDebugModelMessages.JDIStackFrame_25, null));
				}
				if (fThread.isSuspended()) {
					// re-index stack frames - See Bug 47198
					fThread.computeStackFrames();
					if (fDepth == -1) {
						// If depth is -1, then this is an invalid frame
						throw new DebugException(new Status(IStatus.ERROR,
								JDIDebugPlugin.getUniqueIdentifier(),
								IJavaStackFrame.ERR_INVALID_STACK_FRAME,
								JDIDebugModelMessages.JDIStackFrame_25, null));
					}
				} else {
					throw new DebugException(new Status(IStatus.ERROR,
							JDIDebugPlugin.getUniqueIdentifier(),
							IJavaThread.ERR_THREAD_NOT_SUSPENDED,
							JDIDebugModelMessages.JDIStackFrame_25, null));
				}
			}
			return fStackFrame;
		}
	}

	/**
	 * Sets the underlying JDI StackFrame. Called by a thread when incrementally
	 * updating after a step has completed.
	 * 
	 * @param frame
	 *            The underlying stack frame
	 */
	protected void setUnderlyingStackFrame(StackFrame frame) {
		synchronized (fThread) {
			fStackFrame = frame;
			if (frame == null) {
				fRefreshVariables = true;
			}
		}
	}

	protected void setThread(JDIThread thread) {
		fThread = thread;
	}

	protected void setVariables(List<IJavaVariable> variables) {
		fVariables = variables;
	}

	/**
	 * @see IJavaStackFrame#getLocalVariables()
	 */
	@Override
	public IJavaVariable[] getLocalVariables() throws DebugException {
		List<LocalVariable> list = getUnderlyingVisibleVariables();
		IJavaVariable[] locals = new IJavaVariable[list.size()];
		for (int i = 0; i < list.size(); i++) {
			locals[i] = new JDILocalVariable(this, list.get(i));
		}
		return locals;
	}

	/**
	 * @see IJavaStackFrame#getThis()
	 */
	@Override
	public IJavaObject getThis() throws DebugException {
		IJavaObject receiver = null;
		if (!isStatic() && !isNative()) {
			ObjectReference thisObject = getUnderlyingThisObject();
			if (thisObject != null) {
				receiver = (IJavaObject) JDIValue.createValue(
						(JDIDebugTarget) getDebugTarget(), thisObject);
			}
		}
		return receiver;
	}

	/**
	 * Java stack frames do not support registers
	 * 
	 * @see IStackFrame#getRegisterGroups()
	 */
	@Override
	public IRegisterGroup[] getRegisterGroups() {
		return new IRegisterGroup[0];
	}

	/**
	 * @see IJavaStackFrame#getDeclaringType()
	 */
	@Override
	public IJavaClassType getDeclaringType() throws DebugException {
		Method method = getUnderlyingMethod();
		try {
			Type type = method.declaringType();
			if (type instanceof ClassType) {
				return (IJavaClassType) JDIType.createType(
						(JDIDebugTarget) getDebugTarget(), type);
			}
			targetRequestFailed(JDIDebugModelMessages.JDIStackFrame_0, null);
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIStackFrame_exception_retreiving_declaring_type,
							e.toString()), e);
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaStackFrame#getReferenceType()
	 */
	@Override
	public IJavaReferenceType getReferenceType() throws DebugException {
		Method method = getUnderlyingMethod();
		try {
			Type type = method.declaringType();
			return (IJavaReferenceType) JDIType.createType(
					(JDIDebugTarget) getDebugTarget(), type);
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIStackFrame_exception_retreiving_declaring_type,
							e.toString()), e);
		}
		return null;
	}

	/**
	 * Expression level stepping not supported.
	 * 
	 * @see IStackFrame#getCharEnd()
	 */
	@Override
	public int getCharEnd() {
		return -1;
	}

	/**
	 * Expression level stepping not supported.
	 * 
	 * @see IStackFrame#getCharStart()
	 */
	@Override
	public int getCharStart() {
		return -1;
	}

	/**
	 * Clears the cached data of this stack frame. The underlying stack frame
	 * has changed in such a way that the cached data may not be valid.
	 */
	private void clearCachedData() {
		fThisObject = null;
		fReceivingTypeName = null;
	}

	/**
	 * @see IJavaStackFrame#wereLocalsAvailable()
	 */
	@Override
	public boolean wereLocalsAvailable() {
		return fLocalsAvailable;
	}

	/**
	 * Sets whether locals were available. If the setting is not the same as the
	 * current value, a change event is fired such that a UI client can update.
	 * 
	 * @param available
	 *            whether local variable information is available for this stack
	 *            frame.
	 */
	private void setLocalsAvailable(boolean available) {
		if (available != fLocalsAvailable) {
			fLocalsAvailable = available;
			fireChangeEvent(DebugEvent.STATE);
		}
	}

	/**
	 * @see IStackFrame#hasRegisterGroups()
	 */
	@Override
	public boolean hasRegisterGroups() {
		return false;
	}

	/**
	 * @see IStackFrame#hasVariables()
	 */
	@Override
	public boolean hasVariables() throws DebugException {
		return getVariables0().size() > 0;
	}

	/**
	 * @see org.eclipse.debug.core.model.IFilteredStep#canStepWithFilters()
	 */
	@Override
	public boolean canStepWithFilters() {
		if (canStepInto()) {
			String[] filters = getJavaDebugTarget().getStepFilters();
			return filters != null && filters.length > 0;
		}
		return false;
	}

	/**
	 * @see org.eclipse.debug.core.model.IFilteredStep#stepWithFilters()
	 */
	@Override
	public void stepWithFilters() throws DebugException {
		((IJavaThread) getThread()).stepWithFilters();
	}

	/**
	 * @see org.eclipse.jdt.debug.core.IJavaStackFrame#getSourcePath(java.lang.String)
	 */
	@Override
	public String getSourcePath(String stratum) throws DebugException {
		synchronized (fThread) {
			try {
				return fLocation.sourcePath(stratum);
			} catch (AbsentInformationException e) {
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIStackFrame_exception_retrieving_source_path,
								e.toString()), e);
			}
		}
		return null;
	}

	/**
	 * @see org.eclipse.jdt.debug.core.IJavaStackFrame#getSourcePath()
	 */
	@Override
	public String getSourcePath() throws DebugException {
		synchronized (fThread) {
			try {
				return fLocation.sourcePath();
			} catch (AbsentInformationException e) {
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIStackFrame_exception_retrieving_source_path,
								e.toString()), e);
			}
		}
		return null;
	}

	/*
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaStackFrame#getLineNumber(java.lang.String
	 * )
	 */
	@Override
	public int getLineNumber(String stratum) throws DebugException {
		synchronized (fThread) {
			try {
				return fLocation.lineNumber(stratum);
			} catch (RuntimeException e) {
				if (getThread().isSuspended()) {
					targetRequestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIStackFrame_exception_retrieving_line_number,
									e.toString()), e);
				}
			}
		}
		return -1;
	}

	/*
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaStackFrame#getSourceName(java.lang.String
	 * )
	 */
	@Override
	public String getSourceName(String stratum) throws DebugException {
		synchronized (fThread) {
			try {
				return fLocation.sourceName(stratum);
			} catch (AbsentInformationException e) {
			} catch (NativeMethodException e) {
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIStackFrame_exception_retrieving_source_name,
								e.toString()), e);
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaStackFrame#isVarargs()
	 */
	@Override
	public boolean isVarArgs() throws DebugException {
		return getUnderlyingMethod().isVarArgs();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.debug.core.IJavaStackFrame#canForceReturn()
	 */
	@Override
	public boolean canForceReturn() {
		if (getJavaDebugTarget().supportsForceReturn() && isSuspended()) {
			try {
				if (!isNative()) {
					if (isTopStackFrame()) {
						return true;
					}
					List<IJavaStackFrame> frames = fThread.computeStackFrames();
					int index = frames.indexOf(this);
					if (index > 0) {
						JDIStackFrame prev = (JDIStackFrame) frames
								.get(index - 1);
						return prev.canDropToFrame();
					}
				}
			} catch (DebugException e) {
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaStackFrame#forceReturn(org.eclipse.jdt
	 * .debug.core.IJavaValue)
	 */
	@Override
	public void forceReturn(IJavaValue value) throws DebugException {
		if (isTopStackFrame()) {
			fThread.forceReturn(value);
		} else {
			// first check assignment compatible
			Method method = getUnderlyingMethod();
			try {
				ValueImpl.checkValue(((JDIValue) value).getUnderlyingValue(),
						method.returnType(),
						(VirtualMachineImpl) method.virtualMachine());
			} catch (InvalidTypeException e) {
				targetRequestFailed(JDIDebugModelMessages.JDIStackFrame_26, e);
			} catch (ClassNotLoadedException e) {
				targetRequestFailed(JDIDebugModelMessages.JDIThread_48, e);
			}
			List<IJavaStackFrame> frames = fThread.computeStackFrames();
			int index = frames.indexOf(this);
			if (index > 0) {
				JDIStackFrame prev = (JDIStackFrame) frames.get(index - 1);
				fThread.popFrame(prev);
				fThread.forceReturn(value);
			}
		}
	}

	public void setIsTop(boolean isTop) {
		this.fIsTop = isTop;
	}
}
