/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.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;
	}

}
