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

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IMarker;
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.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.eval.ICodeSnippetRequestor;
import org.eclipse.jdt.core.eval.IEvaluationContext;
import org.eclipse.jdt.debug.core.IEvaluationRunnable;
import org.eclipse.jdt.debug.core.IJavaClassObject;
import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
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.IClassFileEvaluationEngine;
import org.eclipse.jdt.debug.eval.IEvaluationEngine;
import org.eclipse.jdt.debug.eval.IEvaluationListener;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIValue;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.InvocationException;
import com.sun.jdi.ObjectReference;

/**
 * An evaluation engine that deploys class files locally
 */

public class LocalEvaluationEngine implements IClassFileEvaluationEngine,
		ICodeSnippetRequestor, IEvaluationRunnable {

	private static final String CODE_SNIPPET_NAME = "CodeSnippet.class"; //$NON-NLS-1$

	/**
	 * A count of the number of engines created. Count is incremented on
	 * instantiation and decremented on dispose. When the count == 0, the
	 * special CodeSnippet.class is deleted as this class file is shared by all.
	 */
	private static int ENGINE_COUNT = 0;

	/**
	 * The Java project context in which to compile snippets.
	 */
	private IJavaProject fJavaProject;

	/**
	 * The debug target on which to execute snippets
	 */
	private IJavaDebugTarget fDebugTarget;

	/**
	 * The location in which to deploy snippet class files
	 */
	private File fOutputDirectory;

	/**
	 * The listener to notify when the current evaluation is complete.
	 */
	private IEvaluationListener fListener;

	/**
	 * The stack frame context for the current evaluation or <code>null</code>
	 * if there is no stack frame context.
	 */
	private IJavaStackFrame fStackFrame;

	/**
	 * The result of this evaluation
	 */
	private EvaluationResult fResult;

	/**
	 * Collection of deployed snippet class files
	 */
	private List<File> fSnippetFiles;

	/**
	 * Collection of directories created by this evaluation engine.
	 */
	private List<File> fDirectories;

	/**
	 * Evaluation context for the Java project associated with this evaluation
	 * engine.
	 */
	private IEvaluationContext fEvaluationContext;

	/**
	 * Array of modifier constants for visible local variables in the current
	 * evaluation.
	 *
	 * XXX: constants should be 'default' or 'final'. Where are these constants
	 * defined.
	 */
	private int[] fLocalVariableModifiers;

	/**
	 * Array of names of visible local variables in the current evaluation.
	 */
	private String[] fLocalVariableNames;

	/**
	 * Array of type names of visible local variables in the current evaluation.
	 */
	private String[] fLocalVariableTypeNames;

	/**
	 * The 'this' object for the current evaluation or <code>null</code> if
	 * there is no 'this' context (static method, or not context)
	 */
	private IJavaObject fThis;

	/**
	 * Whether this engine has been disposed.
	 */
	private boolean fDisposed = false;

	/**
	 * The number of evaluations currently being performed.
	 */
	private int fEvaluationCount = 0;

	/**
	 * The name of the code snippet class to instantiate
	 */
	private String fCodeSnippetClassName = null;

	/**
	 * Whether to hit breakpoints in the evaluation thread
	 */
	private boolean fHitBreakpoints = false;

	/**
	 * Constant for empty array of <code>java.lang.String</code>
	 */
	private static final String[] EMPTY_STRING_ARRAY = new String[0];

	/**
	 * Constant for empty array of <code>int</code>
	 */
	private static final int[] EMPTY_INT_ARRAY = new int[0];

	/**
	 * Constructs a new evaluation engine for the given VM in the context of the
	 * specified project. Class files required for the evaluation will be
	 * deployed to the specified directory (which must be on the class path of
	 * the VM in order for evaluation to work).
	 *
	 * @param project
	 *            context in which to compile snippets
	 * @param vm
	 *            debug target in which to evaluate snippets
	 * @param directory
	 *            location where snippet class files will be deployed for
	 *            execution. The directory must exist
	 */
	public LocalEvaluationEngine(IJavaProject project, IJavaDebugTarget vm,
			File directory) {
		setJavaProject(project);
		setDebugTarget(vm);
		setOutputDirectory(directory);
		ENGINE_COUNT++;
	}

	/**
	 * @see ICodeSnippetRequestor#acceptClassFiles(byte[][], String[][], String)
	 */
	@Override
	public boolean acceptClassFiles(byte[][] classFileBytes,
			String[][] classFileCompoundNames, String codeSnippetClassName) {
		try {
			deploy(classFileBytes, classFileCompoundNames);
		} catch (DebugException e) {
			getResult().setException(e);
			return false;
		}
		if (codeSnippetClassName != null) {
			setCodeSnippetClassName(codeSnippetClassName);
			try {
				getThread().runEvaluation(this, null, DebugEvent.EVALUATION,
						getHitBreakpoints());
			} catch (DebugException e) {
				// exception handling is in evaluation runnable
			}
		}
		return true;
	}

	@Override
	public void run(IJavaThread thread, IProgressMonitor monitor) {
		IJavaObject codeSnippetInstance = null;
		try {
			codeSnippetInstance = newInstance(getCodeSnippetClassName());
			initializeLocals(codeSnippetInstance);
			codeSnippetInstance.sendMessage(RUN_METHOD,	"()V", null, getThread(), false); //$NON-NLS-1$
			restoreLocals(codeSnippetInstance);

			// now retrieve the description of the result
			IVariable[] fields = codeSnippetInstance.getVariables();
			IJavaVariable resultValue = null;
			IJavaVariable resultType = null;
			for (IVariable field : fields) {
				if (field.getName().equals(RESULT_TYPE_FIELD)) {
					resultType = (IJavaVariable) field;
				}
				if (field.getName().equals(RESULT_VALUE_FIELD)) {
					resultValue = (IJavaVariable) field;
				}
			}
			IJavaValue result = convertResult((IJavaClassObject) resultType.getValue(), (IJavaValue) resultValue.getValue());
			getResult().setValue(result);
		} catch (DebugException e) {
			getResult().setException(e);

			Throwable underlyingException = e.getStatus().getException();
			if (underlyingException instanceof InvocationException) {
				ObjectReference theException = ((InvocationException) underlyingException)
						.exception();
				if (theException != null) {
					try {
						try {
							IJavaObject v = (IJavaObject) JDIValue.createValue(
									(JDIDebugTarget) getDebugTarget(),
									theException);
							v.sendMessage(
									"printStackTrace", "()V", null, getThread(), false); //$NON-NLS-2$ //$NON-NLS-1$
						} catch (DebugException de) {
							JDIDebugPlugin.log(de);
						}
					} catch (RuntimeException re) {
						JDIDebugPlugin.log(re);
					}
				}
			}
		}

	}

	/**
	 * Initializes the value of instance variables in the 'code snippet object'
	 * that are used as place-holders for locals and 'this' in the current stack
	 * frame.
	 *
	 * @param object
	 *            instance of code snippet class that will be run
	 * @exception DebugException
	 *                if an exception is thrown accessing the given object
	 */
	protected void initializeLocals(IJavaObject object) throws DebugException {
		IJavaVariable[] locals = null;
		IJavaObject thisObject = getThis();
		if (getStackFrame() != null) {
			locals = getStackFrame().getLocalVariables();
		}
		if (locals != null) {
			for (IJavaVariable local : locals) {
				IJavaVariable field = object.getField(
						LOCAL_VAR_PREFIX + local.getName(), false);
				// internal error if field is not found
				if (field == null) {
					throw new DebugException(
							new Status(
									IStatus.ERROR,
									JDIDebugModel.getPluginIdentifier(),
									DebugException.REQUEST_FAILED,
									EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_initialize_local_variables__4,
									null));
				}
				field.setValue(local.getValue());
			}
		}
		if (thisObject != null) {
			IJavaVariable field = object.getField(DELEGATE_THIS, false);
			// internal error if field is not found
			if (field == null) {
				throw new DebugException(
						new Status(
								IStatus.ERROR,
								JDIDebugModel.getPluginIdentifier(),
								DebugException.REQUEST_FAILED,
								EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_initialize___this___context__5,
								null));
			}
			field.setValue(thisObject);
		}
	}

	/**
	 * Restores the value local variables from the instance variables in the
	 * 'code snippet object' that are used as place-holders for locals in the
	 * current stack frame.
	 *
	 * @param object
	 *            instance of code snippet class that was run
	 * @exception DebugException
	 *                if an exception is thrown accessing the given object
	 */
	protected void restoreLocals(IJavaObject object) throws DebugException {
		IJavaVariable[] locals = null;
		if (getStackFrame() != null) {
			locals = getStackFrame().getLocalVariables();
		}
		if (locals != null) {
			for (IJavaVariable local : locals) {
				IJavaVariable field = object.getField(
						LOCAL_VAR_PREFIX + local.getName(), false);
				// internal error if field is not found
				if (field == null) {
					throw new DebugException(
							new Status(
									IStatus.ERROR,
									JDIDebugModel.getPluginIdentifier(),
									DebugException.REQUEST_FAILED,
									EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_initialize_local_variables__6,
									null));
				}
				local.setValue(field.getValue());
			}
		}
	}

	/**
	 * @see ICodeSnippetRequestor#acceptProblem(IMarker, String, int)
	 */
	@Override
	public void acceptProblem(IMarker problemMarker, String fragmentSource,
			int fragmentKind) {
		if (problemMarker.getAttribute(IMarker.SEVERITY, -1) != IMarker.SEVERITY_ERROR) {
			return;
		}
		getResult().addError(problemMarker.getAttribute(IMarker.MESSAGE, "")); //$NON-NLS-1$
	}

	/**
	 * @see IEvaluationEngine#getDebugTarget()
	 */
	@Override
	public IJavaDebugTarget getDebugTarget() {
		return fDebugTarget;
	}

	/**
	 * Sets the debug target in which snippets are executed.
	 *
	 * @param debugTarget
	 *            the debug target in which snippets are executed
	 */
	private void setDebugTarget(IJavaDebugTarget debugTarget) {
		fDebugTarget = debugTarget;
	}

	/**
	 * @see IEvaluationEngine#getJavaProject()
	 */
	@Override
	public IJavaProject getJavaProject() {
		return fJavaProject;
	}

	/**
	 * Sets the Java project in which snippets are compiled.
	 *
	 * @param javaProject
	 *            the Java project in which snippets are compiled
	 */
	private void setJavaProject(IJavaProject javaProject) {
		fJavaProject = javaProject;
	}

	/**
	 * Returns the directory in which snippet class files are deployed.
	 *
	 * @return the directory in which snippet class files are deployed.
	 */
	public File getOutputDirectory() {
		return fOutputDirectory;
	}

	/**
	 * Sets the directory in which snippet class files are deployed.
	 *
	 * @param outputDirectory
	 *            location to deploy snippet class files
	 */
	private void setOutputDirectory(File outputDirectory) {
		fOutputDirectory = outputDirectory;
	}

	/**
	 * @see IClassFileEvaluationEngine#evaluate(String, IJavaThread,
	 *      IEvaluationListener)
	 */
	@Override
	public void evaluate(String snippet, IJavaThread thread,
			IEvaluationListener listener, boolean hitBreakpoints)
			throws DebugException {
		checkDisposed();
		checkEvaluating();
		try {
			evaluationStarted();
			setListener(listener);
			setHitBreakpoints(hitBreakpoints);
			setResult(new EvaluationResult(this, snippet, thread));
			checkThread();
			// no receiver/stack frame context
			setThis(null);
			setLocalVariableNames(EMPTY_STRING_ARRAY);
			setLocalVariableTypeNames(EMPTY_STRING_ARRAY);
			setLocalVariableModifiers(EMPTY_INT_ARRAY);

			// do the evaluation in a different thread
			Runnable r = new Runnable() {
				@Override
				public void run() {
					try {
						LocalEvaluationEngine.this
								.getEvaluationContext()
								.evaluateCodeSnippet(
										LocalEvaluationEngine.this.getSnippet(),
										LocalEvaluationEngine.this, null);
					} catch (JavaModelException e) {
						LocalEvaluationEngine.this.getResult().setException(
								new DebugException(e.getStatus()));
					} finally {
						LocalEvaluationEngine.this.evaluationComplete();
					}
				}
			};

			Thread t = new Thread(r);
			t.setDaemon(true);
			t.start();
		} catch (DebugException d) {
			evaluationAborted();
			throw d;
		}

	}

	/**
	 * @see IEvaluationEngine#evaluate(String, IJavaStackFrame,
	 *      IEvaluationListener, int)
	 */
	@Override
	public void evaluate(String snippet, IJavaStackFrame frame,
			IEvaluationListener listener, int evaluationDetail,
			boolean hitBreakpoints) throws DebugException {
		checkDisposed();
		checkEvaluating();
		try {
			evaluationStarted();
			setListener(listener);
			setStackFrame(frame);
			setHitBreakpoints(hitBreakpoints);
			setResult(new EvaluationResult(this, snippet,
					(IJavaThread) frame.getThread()));
			checkThread();

			// set up local variables and 'this' context for evaluation
			IJavaVariable[] locals = frame.getLocalVariables();

			List<String> typeNames = new ArrayList<>(locals.length);
			List<String> varNames = new ArrayList<>(locals.length);

			for (IJavaVariable var : locals) {
				String typeName = getTranslatedTypeName(var
						.getReferenceTypeName());
				if (typeName != null) {
					typeNames.add(typeName);
					varNames.add(var.getName());
				}
			}

			setLocalVariableTypeNames(typeNames
					.toArray(new String[typeNames.size()]));
			setLocalVariableNames(varNames
					.toArray(new String[varNames.size()]));
			int[] modifiers = new int[typeNames.size()];
			// cannot determine if local is final, so specify as default
			Arrays.fill(modifiers, 0);
			setLocalVariableModifiers(modifiers);
			setThis(frame.getThis());

			final boolean isStatic = frame.isStatic();
			final boolean isConstructor = frame.isConstructor();
			final IType receivingType = JavaDebugUtils
					.resolveDeclaringType(frame);
			validateReceivingType(receivingType);

			// do the evaluation in a different thread
			Runnable r = new Runnable() {
				@Override
				public void run() {
					try {
						LocalEvaluationEngine.this
								.getEvaluationContext()
								.evaluateCodeSnippet(
										LocalEvaluationEngine.this.getSnippet(),
										LocalEvaluationEngine.this
												.getLocalVariableTypeNames(),
										LocalEvaluationEngine.this
												.getLocalVariableNames(),
										LocalEvaluationEngine.this
												.getLocalVariableModifiers(),
										receivingType, isStatic, isConstructor,
										LocalEvaluationEngine.this, null);
					} catch (JavaModelException e) {
						LocalEvaluationEngine.this.getResult().setException(
								new DebugException(e.getStatus()));
					} finally {
						LocalEvaluationEngine.this.evaluationComplete();
					}
				}
			};

			Thread t = new Thread(r);
			t.setDaemon(true);
			t.start();
		} catch (DebugException d) {
			evaluationAborted();
			throw d;
		} catch (CoreException e) {
			evaluationAborted();
			throw new DebugException(e.getStatus());
		}
	}

	/**
	 * Verifies the receiving type was resolved and is not an inner type.
	 *
	 * @param receivingType
	 * @throws DebugException
	 */
	private void validateReceivingType(final IType receivingType)
			throws DebugException {
		if (receivingType == null) {
			throw new DebugException(
					new Status(
							IStatus.ERROR,
							JDIDebugModel.getPluginIdentifier(),
							DebugException.REQUEST_FAILED,
							EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_determine_receiving_type_context__18,
							null));
		}

		if (receivingType.getDeclaringType() != null) {
			throw new DebugException(
					new Status(
							IStatus.ERROR,
							JDIDebugModel.getPluginIdentifier(),
							DebugException.REQUEST_FAILED,
							EvaluationMessages.LocalEvaluationEngine_Evaluation_in_context_of_inner_type_not_supported__19,
							null));
		}
	}

	/**
	 * @see IEvaluationEngine#evaluate(String, IJavaObject, IJavaThread,
	 *      IEvaluationListener, int)
	 */
	@Override
	public void evaluate(String snippet, IJavaObject thisContext,
			IJavaThread thread, IEvaluationListener listener,
			int evaluationDetail, boolean hitBreakpoints) throws DebugException {
		checkDisposed();
		checkEvaluating();
		try {
			evaluationStarted();
			setListener(listener);
			setHitBreakpoints(hitBreakpoints);
			setResult(new EvaluationResult(this, snippet, thread));
			checkThread();

			// no locals
			setLocalVariableTypeNames(new String[0]);
			setLocalVariableNames(new String[0]);
			setLocalVariableModifiers(new int[0]);

			setThis(thisContext);

			final boolean isStatic = false;
			final boolean isConstructor = false;
			final IType receivingType = JavaDebugUtils.resolveType(thisContext
					.getJavaType());
			validateReceivingType(receivingType);

			// do the evaluation in a different thread
			Runnable r = new Runnable() {
				@Override
				public void run() {
					try {
						LocalEvaluationEngine.this
								.getEvaluationContext()
								.evaluateCodeSnippet(
										LocalEvaluationEngine.this.getSnippet(),
										LocalEvaluationEngine.this
												.getLocalVariableTypeNames(),
										LocalEvaluationEngine.this
												.getLocalVariableNames(),
										LocalEvaluationEngine.this
												.getLocalVariableModifiers(),
										receivingType, isStatic, isConstructor,
										LocalEvaluationEngine.this, null);
					} catch (JavaModelException e) {
						LocalEvaluationEngine.this.getResult().setException(
								new DebugException(e.getStatus()));
					} finally {
						LocalEvaluationEngine.this.evaluationComplete();
					}
				}
			};

			Thread t = new Thread(r);
			t.setDaemon(true);
			t.start();
		} catch (DebugException d) {
			evaluationAborted();
			throw d;
		} catch (CoreException e) {
			evaluationAborted();
			throw new DebugException(e.getStatus());
		}
	}

	/**
	 * Throws an exception if this engine has already been disposed.
	 *
	 * @exception DebugException
	 *                if this engine has been disposed
	 */
	protected void checkDisposed() throws DebugException {
		if (isDisposed()) {
			throw new DebugException(
					new Status(
							IStatus.ERROR,
							JDIDebugModel.getPluginIdentifier(),
							DebugException.REQUEST_FAILED,
							EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___evaluation_context_has_been_disposed__7,
							null));
		}
	}

	/**
	 * Throws an exception if this engine is already in an evaluation.
	 *
	 * @exception DebugException
	 *                if this engine is currently performing an evaluation
	 */
	protected void checkEvaluating() throws DebugException {
		if (isEvaluating()) {
			throw new DebugException(new Status(IStatus.ERROR,
					JDIDebugModel.getPluginIdentifier(),
					DebugException.REQUEST_FAILED,
					"Cannot perform nested evaluations.", null) //$NON-NLS-1$
			);
		}
	}

	/**
	 * Throws an exception if this engine's current evaluation thread is not
	 * suspended.
	 *
	 * @exception DebugException
	 *                if this engine's current evaluation thread is not
	 *                suspended
	 */
	protected void checkThread() throws DebugException {
		if (!getThread().isSuspended()) {
			throw new DebugException(
					new Status(
							IStatus.ERROR,
							JDIDebugModel.getPluginIdentifier(),
							DebugException.REQUEST_FAILED,
							EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___evaluation_thread_must_be_suspended__8,
							null));
		}
	}

	/**
	 * Deletes deployed class files, and clears state.
	 *
	 * @see IEvaluationEngine#dispose()
	 */
	@Override
	public void dispose() {
		fDisposed = true;
		ENGINE_COUNT--;
		if (isEvaluating()) {
			// cannot dispose if in an evaluation, must
			// wait for evaluation to complete
			return;
		}
		List<File> snippetFiles = getSnippetFiles();
		Iterator<File> iter = snippetFiles.iterator();
		while (iter.hasNext()) {
			File file = iter.next();
			if (file.exists()) {
				if (CODE_SNIPPET_NAME.equals(file.getName())
						&& ENGINE_COUNT > 0) {
					continue; // do not delete the common file for other engines
				}
				if (!file.delete()) {
					JDIDebugPlugin
							.log(new Status(
									IStatus.ERROR,
									JDIDebugModel.getPluginIdentifier(),
									DebugException.REQUEST_FAILED,
									MessageFormat
											.format("Unable to delete temporary evaluation class file {0}.", new Object[] { file.getAbsolutePath() }), null) //$NON-NLS-1$
							);
				}
			}
		}
		List<File> directories = getDirectories();
		// remove directories in bottom up order
		int i = directories.size() - 1;
		while (i >= 0) {
			File dir = directories.get(i);
			String[] listing = dir.list();
			if (dir.exists() && listing != null && listing.length == 0
					&& !dir.delete()) {
				JDIDebugPlugin
						.log(new Status(
								IStatus.ERROR,
								JDIDebugModel.getPluginIdentifier(),
								DebugException.REQUEST_FAILED,
								MessageFormat
										.format("Unable to delete temporary evaluation directory {0}.", new Object[] { dir.getAbsolutePath() }), null) //$NON-NLS-1$
						);
			}
			i--;
		}
		reset();
		setJavaProject(null);
		setDebugTarget(null);
		setOutputDirectory(null);
		setResult(null);
		setEvaluationContext(null);
	}

	/**
	 * Resets this engine for another evaluation.
	 */
	private void reset() {
		setThis(null);
		setStackFrame(null);
		setListener(null);
	}

	/**
	 * Returns the listener to notify when the current evaluation is complete.
	 *
	 * @return the listener to notify when the current evaluation is complete
	 */
	protected IEvaluationListener getListener() {
		return fListener;
	}

	/**
	 * Sets the listener to notify when the current evaluation is complete.
	 *
	 * @param listener
	 *            the listener to notify when the current evaluation is complete
	 */
	private void setListener(IEvaluationListener listener) {
		fListener = listener;
	}

	/**
	 * Returns the stack frame context for the current evaluation, or
	 * <code>null</code> if none.
	 *
	 * @return the stack frame context for the current evaluation, or
	 *         <code>null</code> if none
	 */
	protected IJavaStackFrame getStackFrame() {
		return fStackFrame;
	}

	/**
	 * Sets the stack frame context for the current evaluation.
	 *
	 * @param stackFrame
	 *            stack frame context or <code>null</code> if none
	 */
	private void setStackFrame(IJavaStackFrame stackFrame) {
		fStackFrame = stackFrame;
	}

	/**
	 * Returns the thread in which the current evaluation is to be executed.
	 *
	 * @return the thread in which the current evaluation is to be executed
	 */
	protected IJavaThread getThread() {
		return getResult().getThread();
	}

	/**
	 * Returns the code snippet being evaluated.
	 *
	 * @return the code snippet being evaluated.
	 */
	protected String getSnippet() {
		return getResult().getSnippet();
	}

	/**
	 * Returns the current evaluation result.
	 *
	 * @return the current evaluation result
	 */
	protected EvaluationResult getResult() {
		return fResult;
	}

	/**
	 * Sets the current evaluation result.
	 *
	 * @param result
	 *            the current evaluation result
	 */
	private void setResult(EvaluationResult result) {
		fResult = result;
	}

	/**
	 * Deploys the given class files to this engine's output location, and adds
	 * the files to this engines list of temporary files to be deleted when
	 * disposed.
	 *
	 * @exception DebugException
	 *                if this fails due to a lower level exception.
	 */
	protected void deploy(byte[][] classFiles, String[][] classFileNames)
			throws DebugException {
		for (int i = 0; i < classFiles.length; i++) {
			String[] compoundName = classFileNames[i];
			// create required folders
			File dir = LocalEvaluationEngine.this.getOutputDirectory();
			try {
				String pkgDirName = dir.getCanonicalPath();
				for (int j = 0; j < (compoundName.length - 1); j++) {
					pkgDirName += File.separator + compoundName[j];
					File pkgDir = new File(pkgDirName);
					if (!pkgDir.exists()) {
						pkgDir.mkdir();
						addDirectory(pkgDir);
					}
				}
				String name = compoundName[compoundName.length - 1] + ".class"; //$NON-NLS-1$
				File classFile = new File(pkgDirName + File.separator + name);
				if (!classFile.exists()) {
					classFile.createNewFile();
				}
				try (FileOutputStream stream = new FileOutputStream(classFile)) {
					stream.write(classFiles[i]);
				}
				LocalEvaluationEngine.this.addSnippetFile(classFile);
			} catch (IOException e) {
				throw new DebugException(
						new Status(
								IStatus.ERROR,
								JDIDebugModel.getPluginIdentifier(),
								DebugException.REQUEST_FAILED,
								MessageFormat
										.format(EvaluationMessages.LocalEvaluationEngine__0__occurred_deploying_class_file_for_evaluation_9,
												new Object[] { e.toString() }),
								e));
			}
		}
	}

	/**
	 * Adds the given file to this engine's collection of deployed snippet class
	 * files, which are to be deleted when this engine is disposed.
	 *
	 * @param File
	 *            snippet class file
	 */
	private void addSnippetFile(File file) {
		if (fSnippetFiles == null) {
			fSnippetFiles = new ArrayList<>();
		}
		fSnippetFiles.add(file);
	}

	/**
	 * Adds the given file to this engine's collection of created directories,
	 * which are to be deleted when this engine is disposed.
	 *
	 * @param file
	 *            directory created for class file deployment
	 */
	private void addDirectory(File file) {
		if (fDirectories == null) {
			fDirectories = new ArrayList<>();
		}
		fDirectories.add(file);
	}

	/**
	 * Returns an evaluation context for this evaluation engine. An evaluation
	 * context is associated with a specific Java project. The evaluation context
	 * is created lazily on the first access.
	 *
	 * @return evaluation context
	 */
	protected IEvaluationContext getEvaluationContext() {
		if (fEvaluationContext == null) {
			fEvaluationContext = getJavaProject().newEvaluationContext();
		}
		return fEvaluationContext;
	}

	/**
	 * Sets the evaluation context for this evaluation engine.
	 *
	 * @param context
	 *            evaluation context
	 */
	private void setEvaluationContext(IEvaluationContext context) {
		fEvaluationContext = context;
	}

	/**
	 * Returns a collection of snippet class file deployed by this evaluation
	 * engine, possibly empty.
	 *
	 * @return deployed class files
	 */
	protected List<File> getSnippetFiles() {
		if (fSnippetFiles == null) {
			return Collections.EMPTY_LIST;
		}
		return fSnippetFiles;
	}

	/**
	 * Returns a collection of directories created by this evaluation engine,
	 * possibly empty.
	 *
	 * @return directories created when deploying class files
	 */
	protected List<File> getDirectories() {
		if (fDirectories == null) {
			return Collections.EMPTY_LIST;
		}
		return fDirectories;
	}

	/**
	 * Returns whether this evaluation engine has been disposed.
	 *
	 * @return whether this evaluation engine has been disposed
	 */
	protected boolean isDisposed() {
		return fDisposed;
	}

	/**
	 * The evaluation is complete. Notify the current listener and reset for the
	 * next evaluation.
	 */
	protected void evaluationComplete() {
		// only notify if plug-in not yet shutdown (bug# 8693)
		if (JDIDebugPlugin.getDefault() != null) {
			getListener().evaluationComplete(getResult());
		}
		evaluationEnded();
		reset();
		if (isDisposed()) {
			// if the engine was disposed during an evaluation
			// do the cleanup now
			dispose();
		}
	}

	/**
	 * Increments the evaluation counter.
	 */
	private void evaluationStarted() {
		fEvaluationCount++;
	}

	/**
	 * Decrements the evaluation counter.
	 */
	private void evaluationEnded() {
		if (fEvaluationCount > 0) {
			fEvaluationCount--;
		}
	}

	/**
	 * Returns whether this engine is currently in the midst of an evaluation.
	 */
	protected boolean isEvaluating() {
		return fEvaluationCount > 0;
	}

	/**
	 * Called when an evaluation is aborted due to an exception. Decrements the
	 * evaluation count, and disposes this engine if the target VM disconnected
	 * or terminated during the evaluation attempt.
	 */
	private void evaluationAborted() {
		evaluationEnded();
		if (isDisposed()) {
			// if the engine was disposed during an evaluation
			// do the cleanup now
			dispose();
		}
	}

	/**
	 * Constructs and returns a new instance of the specified class on the
	 * target VM.
	 *
	 * @param className
	 *            fully qualified class name
	 * @return a new instance on the target, as an <code>IJavaValue</code>
	 * @exception DebugException
	 *                if creation fails
	 */
	protected IJavaObject newInstance(String className) throws DebugException {
		IJavaObject object = null;
		IJavaClassType clazz = null;
		IJavaType[] types = getDebugTarget().getJavaTypes(className);
		if (types != null && types.length > 0) {
			clazz = (IJavaClassType) types[0];
		}
		if (clazz == null) {
			// The class is not loaded on the target VM.
			// Force the load of the class.
			types = getDebugTarget().getJavaTypes("java.lang.Class"); //$NON-NLS-1$
			IJavaClassType classClass = null;
			if (types != null && types.length > 0) {
				classClass = (IJavaClassType) types[0];
			}
			if (classClass == null) {
				// unable to load the class
				throw new DebugException(
						new Status(
								IStatus.ERROR,
								JDIDebugModel.getPluginIdentifier(),
								DebugException.REQUEST_FAILED,
								EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___unable_to_instantiate_code_snippet_class__11,
								null));
			}
			IJavaValue[] args = new IJavaValue[] { getDebugTarget().newValue(
					className) };
			IJavaObject classObject = (IJavaObject) classClass
					.sendMessage(
							"forName", "(Ljava/lang/String;)Ljava/lang/Class;", args, getThread()); //$NON-NLS-2$ //$NON-NLS-1$
			object = (IJavaObject) classObject
					.sendMessage(
							"newInstance", "()Ljava/lang/Object;", null, getThread(), false); //$NON-NLS-2$ //$NON-NLS-1$
		} else {
			object = clazz.newInstance("<init>", null, getThread()); //$NON-NLS-1$
		}
		return object;
	}

	/**
	 * Interprets and returns the result of the running the snippet class file.
	 * The type of the result is described by an instance of
	 * <code>java.lang.Class</code>. The value is interpreted based on the
	 * result type.
	 * <p>
	 * Objects as well as primitive data types (boolean, int, etc.), have class
	 * objects, which are created by the VM. If the class object represents a
	 * primitive data type, then the associated value is stored in an instance
	 * of its "object" class. For example, when the result type is the class
	 * object for <code>int</code>, the result object is an instance of
	 * <code>java.lang.Integer</code>, and the actual <code>int</code> is stored
	 * in the </code>intValue()</code>. When the result type is the class object
	 * for <code>java.lang.Integer</code> the result object is an instance of
	 * <code>java.lang.Integer</code>, to be interpreted as a
	 * <code>java.lang.Integer</code>.
	 * </p>
	 *
	 * @param resultType
	 *            the class of the result
	 * @param resultValue
	 *            the value of the result, to be interpreted based on
	 *            resultType
	 * @return the result of running the code snippet class file
	 */
	protected IJavaValue convertResult(IJavaClassObject resultType,
			IJavaValue result) throws DebugException {
		if (resultType == null) {
			// there was an exception or compilation problem - no result
			return null;
		}

		// check the type of the result - if a primitive type, convert it
		String sig = resultType.getInstanceType().getSignature();
		if (sig.equals("V") || sig.equals("Lvoid;")) { //$NON-NLS-2$ //$NON-NLS-1$
			// void
			return getDebugTarget().voidValue();
		}

		if (result.getJavaType() == null) {
			// null result
			return result;
		}

		if (sig.length() == 1) {
			// primitive type - find the instance variable with the
			// signature of the result type we are looking for
			IVariable[] vars = result.getVariables();
			IJavaVariable var = null;
			for (IVariable var2 : vars) {
				IJavaVariable jv = (IJavaVariable) var2;
				if (!jv.isStatic() && jv.getSignature().equals(sig)) {
					var = jv;
					break;
				}
			}
			if (var != null) {
				return (IJavaValue) var.getValue();
			}
		} else {
			// an object
			return result;
		}
		throw new DebugException(
				new Status(
						IStatus.ERROR,
						JDIDebugModel.getPluginIdentifier(),
						DebugException.REQUEST_FAILED,
						EvaluationMessages.LocalEvaluationEngine_Evaluation_failed___internal_error_retreiving_result__17,
						null));
	}

	/**
	 * Returns the modifiers of the local variables visible in this evaluation,
	 * possibly empty.
	 *
	 * @return array of modifiers
	 */
	private int[] getLocalVariableModifiers() {
		return fLocalVariableModifiers;
	}

	/**
	 * Sets the modifiers of the local variables visible in this evaluation,
	 * possibly empty.
	 *
	 * @param localVariableModifiers
	 *            array of modifiers
	 */
	private void setLocalVariableModifiers(int[] localVariableModifiers) {
		fLocalVariableModifiers = localVariableModifiers;
	}

	/**
	 * Returns the names of the local variables visible in this evaluation,
	 * possibly empty.
	 *
	 * @param array
	 *            of names
	 */
	private String[] getLocalVariableNames() {
		return fLocalVariableNames;
	}

	/**
	 * Sets the names of the local variables visible in this evaluation,
	 * possibly empty.
	 *
	 * @param localVariableNames
	 *            array of names
	 */
	private void setLocalVariableNames(String[] localVariableNames) {
		fLocalVariableNames = localVariableNames;
	}

	/**
	 * Returns the type names of the local variables visible in this evaluation,
	 * possibly empty.
	 *
	 * @param array
	 *            of type names
	 */
	private String[] getLocalVariableTypeNames() {
		return fLocalVariableTypeNames;
	}

	/**
	 * Sets the type names of the local variables visible in this evaluation,
	 * possibly empty.
	 *
	 * @param localVariableTypeNames
	 *            array of type names
	 */
	private void setLocalVariableTypeNames(String[] localVariableTypeNames) {
		fLocalVariableTypeNames = localVariableTypeNames;
	}

	/**
	 * Sets the receiver context for the associated evaluation, possibly
	 * <code>null</code> if the evaluation is in the context of a static method
	 * or there is no object context.
	 *
	 * @param thisObject
	 *            the receiver content of the associated evaluation, or
	 *            <code>null</code>
	 */
	private void setThis(IJavaObject thisObject) {
		fThis = thisObject;
	}

	/**
	 * Returns the receiver context for the associated evaluation, or
	 * <code>null</code> if the evaluation is in the context of a static method
	 * or there is no object context.
	 *
	 * @return the receiver context of the associated evaluation or
	 *         <code>null</code>
	 */
	private IJavaObject getThis() {
		return fThis;
	}

	/**
	 * Returns a copy of the type name with '$' replaced by '.', or returns
	 * <code>null</code> if the given type name refers to an anonymous inner
	 * class.
	 *
	 * @param typeName
	 *            a fully qualified type name
	 * @return a copy of the type name with '$' replaced by '.', or returns
	 *         <code>null</code> if the given type name refers to an anonymous
	 *         inner class.
	 */
	protected String getTranslatedTypeName(String typeName) {
		int index = typeName.lastIndexOf('$');
		if (index == -1) {
			return typeName;
		}
		if (index + 1 > typeName.length()) {
			// invalid name
			return typeName;
		}
		String last = typeName.substring(index + 1);
		try {
			Integer.parseInt(last);
			return null;
		} catch (NumberFormatException e) {
			return typeName.replace('$', '.');
		}
	}

	/**
	 * Returns an array of simple type names that are part of the given type's
	 * qualified name. For example, if the given name is <code>x.y.A$B</code>,
	 * an array with <code>["A", "B"]</code> is returned.
	 *
	 * @param typeName
	 *            fully qualified type name
	 * @return array of nested type names
	 */
	protected String[] getNestedTypeNames(String typeName) {
		int index = typeName.lastIndexOf('.');
		if (index >= 0) {
			typeName = typeName.substring(index + 1);
		}
		index = typeName.indexOf('$');
		ArrayList<String> list = new ArrayList<>(1);
		while (index >= 0) {
			list.add(typeName.substring(0, index));
			typeName = typeName.substring(index + 1);
			index = typeName.indexOf('$');
		}
		list.add(typeName);
		return list.toArray(new String[list.size()]);
	}

	/**
	 * @see IClassFileEvaluationEngine#getImports()
	 */
	@Override
	public String[] getImports() {
		return getEvaluationContext().getImports();
	}

	/**
	 * @see IClassFileEvaluationEngine#setImports(String[])
	 */
	@Override
	public void setImports(String[] imports) {
		getEvaluationContext().setImports(imports);
	}

	/**
	 * Sets the name of the code snippet to instantiate to run the current
	 * evaluation.
	 *
	 * @param name
	 *            the name of the deployed code snippet to instantiate and run
	 */
	private void setCodeSnippetClassName(String name) {
		fCodeSnippetClassName = name;
	}

	/**
	 * Returns the name of the code snippet to instantiate to run the current
	 * evaluation.
	 *
	 * @return the name of the deployed code snippet to instantiate and run
	 */
	protected String getCodeSnippetClassName() {
		return fCodeSnippetClassName;
	}

	/**
	 * @see ICodeSnippetRequestor#isRequestingClassFiles()
	 */
	public boolean isRequestingClassFiles() {
		return true;
	}

	/**
	 * Returns whether to hit breakpoints in the evaluation thread.
	 *
	 * @return whether to hit breakpoints in the evaluation thread
	 */
	protected boolean getHitBreakpoints() {
		return fHitBreakpoints;
	}

	/**
	 * Sets whether to hit breakpoints in the evaluation thread.
	 *
	 * @param hit
	 *            whether to hit breakpoints in the evaluation thread
	 */
	private void setHitBreakpoints(boolean hit) {
		fHitBreakpoints = hit;
	}

}
