/*******************************************************************************
 * 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.debug.jdi.tests;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;

import org.eclipse.jdi.Bootstrap;

import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ArrayReference;
import com.sun.jdi.ArrayType;
import com.sun.jdi.ClassLoaderReference;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.StackFrame;
import com.sun.jdi.StringReference;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachineManager;
import com.sun.jdi.connect.AttachingConnector;
import com.sun.jdi.connect.Connector.Argument;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.ExceptionEvent;
import com.sun.jdi.event.StepEvent;
import com.sun.jdi.request.AccessWatchpointRequest;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.ExceptionRequest;
import com.sun.jdi.request.ModificationWatchpointRequest;
import com.sun.jdi.request.StepRequest;

import junit.framework.Test;
import junit.framework.TestCase;

/**
 * Tests for com.sun.jdi.* and JDWP commands.
 * These tests assume that the target program is
 * "org.eclipse.debug.jdi.tests.program.MainClass".
 *
 * Examples of arguments:
 *   -launcher SunVMLauncher -address c:\jdk1.2.2\ -cp d:\target
 *   -launcher J9VMLauncher -address d:\ive\ -cp d:\target
 */
public abstract class AbstractJDITest extends TestCase {
	static int TIMEOUT = 10000; //ms
	static protected int fBackEndPort = 9900;
	// We want subsequent connections to use different ports.
	protected static String fVMLauncherName;
	protected static String fTargetAddress;
	protected static String fClassPath;
	protected static String fBootPath;
	protected static String fVMType;
	protected com.sun.jdi.VirtualMachine fVM;
	protected Process fLaunchedProxy;
	protected Process fLaunchedVM;
	protected static int fVMTraceFlags = com.sun.jdi.VirtualMachine.TRACE_NONE;
	protected EventReader fEventReader;
	protected AbstractReader fConsoleReader;
	protected AbstractReader fConsoleErrorReader;
	protected AbstractReader fProxyReader;
	protected AbstractReader fProxyErrorReader;
	protected boolean fInControl = true;
	// Whether this test should control the VM (ie. starting it and shutting it down)
	protected static boolean fVerbose;
	protected static String fStdoutFile;
	protected static String fStderrFile;
	protected static String fProxyoutFile;
	protected static String fProxyerrFile;
	protected static String fVmCmd;
	protected static String fVmArgs;
	protected static String fProxyCmd;

	// Stack offset to the MainClass.run() method
	protected static final int RUN_FRAME_OFFSET = 1;

	/**
	 * Constructs a test case with a default name.
	 */
	public AbstractJDITest() {
		super("JDI Test");
	}
	/**
	 * Returns the names of the tests that are known to not work
	 * By default, none are excluded.
	 */
	protected String[] excludedTests() {
		return new String[] {
		};
	}
	/**
	 * Creates and returns an access watchpoint request
	 * for the field "fBool" in
	 * org.eclipse.debug.jdi.tests.program.MainClass
	 * NOTE: This assumes that the VM can watch field access.
	 */
	protected AccessWatchpointRequest getAccessWatchpointRequest() {
		// Get the field
		Field field = getField("fBool");

		// Create an access watchpoint for this field
		return fVM.eventRequestManager().createAccessWatchpointRequest(field);
	}
	/**
	 * Returns all tests that start with the given string.
	 * Returns a vector of String.
	 */
	protected Vector<String> getAllMatchingTests(String match) {
		Class<? extends AbstractJDITest> theClass = this.getClass();
		java.lang.reflect.Method[] methods = theClass.getDeclaredMethods();
		Vector<String> result = new Vector<>();
		for (int i = 0; i < methods.length; i++) {
			java.lang.reflect.Method m = methods[i];
			String name = m.getName();
			Class<?>[] parameters = m.getParameterTypes();
			if (parameters.length == 0 && name.startsWith(match)) {
				if (!isExcludedTest(name)) {
					result.add(name);
				} else {
					System.out.println(name + " is excluded.");
				}
			}
		}
		return result;
	}

	/**
	 * Returns if the current VM version is greater than or equal to 1.6
	 * @return <code>true</code> if a 1.6 or higher VM
	 * @since 3.8
	 */
	protected boolean is16OrGreater() {
		String ver = fVM.version();
		return ver.indexOf("1.6") > -1 || ver.indexOf("1.7") > -1;
	}

	/**
	 * Returns an array reference.
	 */
	protected ArrayReference getObjectArrayReference() {
		// Get static field "fArray"
		Field field = getField("fArray");

		// Get value of "fArray"
		return (ArrayReference) getMainClass().getValue(field);
	}

	/**
	 * Returns another array reference.
	 */
	protected ArrayReference getNonEmptyDoubleArrayReference() {
		// Get static field "fDoubleArray"
		Field field = getField("fDoubleArray");

		// Get value of "fDoubleArray"
		return (ArrayReference) getMainClass().getValue(field);
	}

	/**
	 * One-dimensional empty array reference getters
	 */
	protected ArrayReference getByteArrayReference() {
		Field field = getField("byteArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getShortArrayReference() {
		Field field = getField("shortArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getIntArrayReference() {
		Field field = getField("intArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getLongArrayReference() {
		Field field = getField("longArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getDoubleArrayReference() {
		Field field = getField("doubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getFloatArrayReference() {
		Field field = getField("floatArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getCharArrayReference() {
		Field field = getField("charArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getBooleanArrayReference() {
		Field field = getField("booleanArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	/**
	 * Two-dimensional array reference getters
	 */
	protected ArrayReference getByteDoubleArrayReference() {
		Field field = getField("byteDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getShortDoubleArrayReference() {
		Field field = getField("shortDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getIntDoubleArrayReference() {
		Field field = getField("intDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getLongDoubleArrayReference() {
		Field field = getField("longDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getFloatDoubleArrayReference() {
		Field field = getField("floatDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getDoubleDoubleArrayReference() {
		Field field = getField("doubleDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getCharDoubleArrayReference() {
		Field field = getField("charDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}
	protected ArrayReference getBooleanDoubleArrayReference() {
		Field field = getField("booleanDoubleArray");
		return (ArrayReference) getMainClass().getValue(field);
	}

	/**
	 * Returns the array type.
	 */
	protected ArrayType getArrayType() {
		// Get array reference
		ArrayReference value = getObjectArrayReference();

		// Get reference type of "fArray"
		return (ArrayType) value.referenceType();
	}
	/**
	 * One-dimensional primitive array getters
	 */
	protected ArrayType getByteArrayType() {
		ArrayReference value = getByteArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getShortArrayType() {
		ArrayReference value = getShortArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getIntArrayType() {
		ArrayReference value = getIntArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getLongArrayType() {
		ArrayReference value = getLongArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getFloatArrayType() {
		ArrayReference value = getFloatArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getDoubleArrayType() {
		ArrayReference value = getDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getCharArrayType() {
		ArrayReference value = getCharArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getBooleanArrayType() {
		ArrayReference value = getBooleanArrayReference();
		return (ArrayType) value.referenceType();
	}
	/**
	 * Two-dimensional primitive array getters
	 */
	protected ArrayType getByteDoubleArrayType() {
		ArrayReference value = getByteDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getShortDoubleArrayType() {
		ArrayReference value = getShortDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getIntDoubleArrayType() {
		ArrayReference value = getIntDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getLongDoubleArrayType() {
		ArrayReference value = getLongDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getFloatDoubleArrayType() {
		ArrayReference value = getFloatDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getDoubleDoubleArrayType() {
		ArrayReference value = getDoubleDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getCharDoubleArrayType() {
		ArrayReference value = getCharDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}
	protected ArrayType getBooleanDoubleArrayType() {
		ArrayReference value = getBooleanDoubleArrayReference();
		return (ArrayType) value.referenceType();
	}

	/**
	 * Creates and returns a breakpoint request in the first
	 * instruction of the MainClass.triggerBreakpointEvent() method.
	 */
	protected BreakpointRequest getBreakpointRequest() {
		// Create a breakpoint request
		return fVM.eventRequestManager().createBreakpointRequest(getLocation());
	}

	/**
	 * Creates a new breakpoint request for a user specified position
	 * @param loc the location to set the breakpoint on
	 * @return a new breakpoint request or null if the location is invalid
	 * @since 3.3
	 */
	protected BreakpointRequest getBreakpointRequest(Location loc) {
		return fVM.eventRequestManager().createBreakpointRequest(loc);
	}
	/**
	 * Returns the class with the given name or null if not loaded.
	 */
	protected ClassType getClass(String name) {
		List<?> classes = fVM.classesByName(name);
		if (classes.size() == 0) {
			return null;
		}

		return (ClassType) classes.get(0);
	}
	/**
	 * Returns the class loader of
	 * org.eclipse.debug.jdi.tests.program.MainClass
	 */
	protected ClassLoaderReference getClassLoaderReference() {
		// Get main class
		ClassType type = getMainClass();

		// Get its class loader
		return type.classLoader();
	}
	/**
	 * Creates and returns an exception request for uncaught exceptions.
	 */
	protected ExceptionRequest getExceptionRequest() {
		return fVM.eventRequestManager().createExceptionRequest(null, false, true);
	}
	/**
	 * Returns the static field "fObject" in
	 * org.eclipse.debug.jdi.tests.program.MainClass
	 */
	protected Field getField() {
		return getField("fObject");
	}
	/**
	 * Returns the field with the given name in
	 * org.eclipse.debug.jdi.tests.program.MainClass.
	 */
	protected Field getField(String fieldName) {
		// Get main class
		ClassType type = getMainClass();

		// Get field
		Field result = type.fieldByName(fieldName);
		if (result == null) {
			throw new Error("Unknown field: " + fieldName);
		}

		return result;
	}
	/**
	 * Returns the n frame (starting at the top of the stack) of the thread
	 * contained in the static field "fThread" of org.eclipse.debug.jdi.tests.program.MainClass.
	 */
	protected StackFrame getFrame(int n) {
		// Make sure the thread is suspended
		ThreadReference thread = getThread();
		assertTrue(thread.isSuspended());

		// Get the frame
		StackFrame frame = null;
		try {
			List<?> frames = thread.frames();
			frame = (StackFrame) frames.get(n);
		} catch (IncompatibleThreadStateException e) {
			throw new Error("Thread was not suspended");
		}

		return frame;
	}
	/**
	 * Returns the interface type org.eclipse.debug.jdi.tests.program.Printable.
	 */
	protected InterfaceType getInterfaceType() {
		List<?> types = fVM.classesByName("org.eclipse.debug.jdi.tests.program.Printable");
		return (InterfaceType) types.get(0);
	}
	/**
	 * Returns the variable "t" in the frame running MainClass.run().
	 */
	protected LocalVariable getLocalVariable() {
		try {
			return getFrame(RUN_FRAME_OFFSET).visibleVariableByName("t");
		} catch (AbsentInformationException e) {
			return null;
		}
	}
	/**
	 * Returns the first location in MainClass.print(OutputStream).
	 */
	protected Location getLocation() {
		return getMethod().location();
	}
	/**
	 * Returns the class org.eclipse.debug.jdi.tests.program.MainClass.
	 */
	protected ClassType getMainClass() {
		return getClass( getMainClassName() );
	}
	/**
	 * Returns the method "print(Ljava/io/OutputStream;)V"
	 * in org.eclipse.debug.jdi.tests.program.MainClass
	 */
	protected Method getMethod() {
		return getMethod("print", "(Ljava/io/OutputStream;)V");
	}
	/**
	 * Returns the method with the given name and signature
	 * in org.eclipse.debug.jdi.tests.program.MainClass
	 */
	protected Method getMethod(String name, String signature) {
		return getMethod(
			getMainClassName(),
			name,
			signature);
	}
	/**
	 * Returns the method with the given name and signature
	 * in the given class.
	 */
	protected Method getMethod(String className, String name, String signature) {
		// Get main class
		ClassType type = getClass(className);

		// Get method print(OutputStream)
		Method method = null;
		List<Method> methods = type.methods();
		ListIterator<Method> iterator = methods.listIterator();
		while (iterator.hasNext()) {
			Method m = iterator.next();
			if ((m.name().equals(name)) && (m.signature().equals(signature))) {
				method = m;
				break;
			}
		}
		if (method == null) {
			throw new Error("Unknown method: " + name + signature);
		}

		return method;
	}
	/**
	 * Creates and returns a modification watchpoint request
	 * for the field "fBool" in
	 * org.eclipse.debug.jdi.tests.program.MainClass.
	 * NOTE: This assumes that the VM can watch field modification.
	 */
	protected ModificationWatchpointRequest getModificationWatchpointRequest() {
		// Get the field
		Field field = getField("fBool");

		// Create a modification watchpoint for this field
		return fVM.eventRequestManager().createModificationWatchpointRequest(field);
	}
	/**
	 * Returns the value of the static field "fObject" in
	 * org.eclipse.debug.jdi.tests.program.MainClass
	 */
	protected ObjectReference getObjectReference() {
		// Get main class
		ClassType type = getMainClass();

		// Get field "fObject"
		Field field = getField();

		// Get value of "fObject"
		return (ObjectReference) type.getValue(field);
	}
	/**
	 * Creates and returns an access watchpoint request
	 * for the static field "fString" in
	 * org.eclipse.debug.jdi.tests.program.MainClass
	 * NOTE: This assumes that the VM can watch field access.
	 */
	protected AccessWatchpointRequest getStaticAccessWatchpointRequest() {
		// Get the static field
		Field field = getField("fString");

		// Create an access watchpoint for this field
		return fVM.eventRequestManager().createAccessWatchpointRequest(field);
	}
	/**
	 * Creates and returns a modification watchpoint request
	 * for the static field "fString" in
	 * org.eclipse.debug.jdi.tests.program.MainClass.
	 * NOTE: This assumes that the VM can watch field modification.
	 */
	protected ModificationWatchpointRequest getStaticModificationWatchpointRequest() {
		// Get the field
		Field field = getField("fString");

		// Create a modification watchpoint for this field
		return fVM.eventRequestManager().createModificationWatchpointRequest(field);
	}
	/**
	 * Returns the value of the static field "fString" in
	 * org.eclipse.debug.jdi.tests.program.MainClass
	 */
	protected StringReference getStringReference() {
		// Get field "fString"
		Field field = getField("fString");

		// Get value of "fString"
		return (StringReference) getMainClass().getValue(field);
	}
	/**
	 * Returns the class java.lang.Object.
	 */
	protected ClassType getSystemType() {
		List<ReferenceType> classes = fVM.classesByName("java.lang.Object");
		if (classes.size() == 0) {
			return null;
		}

		return (ClassType) classes.get(0);
	}
	/**
	 * Returns the thread contained in the static field "fThread" in
	 * org.eclipse.debug.jdi.tests.program.MainClass
	 */
	protected ThreadReference getThread() {
		return getThread("fThread");
	}

	protected ThreadReference getMainThread() {
		return getThread("fMainThread");
	}

	private ThreadReference getThread(String fieldName) {
		ClassType type = getMainClass();
		if (type == null) {
			return null;
		}

		// Get static field "fThread"
		List<Field> fields = type.fields();
		ListIterator<Field> iterator = fields.listIterator();
		Field field = null;
		while (iterator.hasNext()) {
			field = iterator.next();
			if (field.name().equals(fieldName)) {
				break;
			}
		}

		// Get value of "fThread"
		Value value = type.getValue(field);
		if (value == null) {
			return null;
		}

		return (ThreadReference) value;
	}
	/**
	 * Returns the VM info for this test.
	 */
	public VMInformation getVMInfo() {
		return new VMInformation(
			fVM,
			fVMType,
			fLaunchedVM,
			fEventReader,
			fConsoleReader);
	}
	/**
	 * Returns whether the given test is excluded for the VM we are testing.
	 */
	private boolean isExcludedTest(String testName) {
		String[] excludedTests = excludedTests();
		if (excludedTests == null) {
			return false;
		}
		for (int i = 0; i < excludedTests.length; i++) {
			if (testName.equals(excludedTests[i])) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Launches the target VM and connects to VM.
	 */
	protected void launchTargetAndConnectToVM() {
		launchTarget();
		connectToVM();
	}

	protected boolean vmIsRunning() {
		boolean isRunning = false;
		try {
			if (fLaunchedVM != null) {
				fLaunchedVM.exitValue();
			}
		} catch (IllegalThreadStateException e) {
			isRunning = true;
		}
		return isRunning;
	}

	protected void launchTarget() {
		if (fVmCmd != null) {
			launchCommandLineTarget();
		} else if (fVMLauncherName.equals("SunVMLauncher")) {
			launchSunTarget();
		} else if (fVMLauncherName.equals("IBMVMLauncher")) {
			launchIBMTarget();
		} else {
			launchJ9Target();
		}
	}

	/**
	 * Launches the target VM specified on the command line.
	 */
	private void launchCommandLineTarget() {
		try {
			if (fProxyCmd != null) {
				fLaunchedProxy = Runtime.getRuntime().exec(parseCommand(fProxyCmd));
			}
			fLaunchedVM = Runtime.getRuntime().exec(parseCommand(fVmCmd));
		} catch (IOException e) {
			throw new Error("Could not launch the VM because " + e.getMessage());
		}
	}

	/**
	 * Parse the command {@link String} to make sure we use
	 * {@link Runtime#exec(String[])}.
	 *
	 * @param command
	 * @return the array of items from the command {@link String}
	 * @since 4.3
	 */
	String[] parseCommand(String command) {
		StringTokenizer tokenizer = new StringTokenizer(command);
		String[] commandArray = new String[tokenizer.countTokens()];
		//first token is the command
		if(tokenizer.hasMoreTokens()) {
			commandArray[0] = tokenizer.nextToken();
		}
		for (int i= 1; tokenizer.hasMoreTokens(); i++) {
			commandArray[i] = tokenizer.nextToken();
		}
		return commandArray;
	}

	/**
	 * Launches the target J9 VM.
	 */
	private void launchJ9Target() {
		try {
			// Launch proxy
			String proxyString[] = new String[3];
			int index = 0;
			String binDirectory =
				fTargetAddress
					+ File.separatorChar
					+ "bin"
					+ File.separatorChar;

			proxyString[index++] = binDirectory + "j9proxy";
			proxyString[index++] = "localhost:" + (fBackEndPort - 1);
			proxyString[index++] = "" + fBackEndPort;
			fLaunchedProxy = Runtime.getRuntime().exec(proxyString);

			// Launch target VM
			Vector<String> commandLine = new Vector<>();

			String launcher = binDirectory + "j9w.exe";
			File vm= new File(launcher);
			if (!vm.exists()) {
				launcher = binDirectory + "j9";
			}
			commandLine.add(launcher);

			if (fBootPath.length() > 0) {
				commandLine.add("-bp:" + fBootPath);
			}
			commandLine.add("-cp:" + fClassPath);
			commandLine.add("-debug:" + (fBackEndPort - 1));
			injectVMArgs(commandLine);
			commandLine.add(getMainClassName());

			fLaunchedVM = exec(commandLine);

		} catch (IOException e) {
			throw new Error("Could not launch the VM because " + e.getMessage());
		}
	}

	/**
	 * Launches the target Sun VM.
	 */
	private void launchSunTarget() {
		try {
			// Launch target VM
			StringBuilder binDirectory= new StringBuilder();
			if (fTargetAddress.endsWith("jre")) {
				binDirectory.append(fTargetAddress.substring(0, fTargetAddress.length() - 4));
			} else {
				binDirectory.append(fTargetAddress);
			}
			binDirectory.append(File.separatorChar);
			binDirectory.append("bin").append(File.separatorChar);

			Vector<String> commandLine = new Vector<>();

			String launcher = binDirectory.toString() + "javaw.exe";
			File vm= new File(launcher);
			if (!vm.exists()) {
				launcher = binDirectory + "java";
			}
			commandLine.add(launcher);

			if (fBootPath.length() > 0) {
				commandLine.add("-bootpath");
				commandLine.add(fBootPath);
			}
			commandLine.add("-classpath");
			commandLine.add(fClassPath);
			commandLine.add("-Xdebug");
			commandLine.add("-Xnoagent");
			commandLine.add("-Djava.compiler=NONE");
			commandLine.add("-Xrunjdwp:transport=dt_socket,address=" + fBackEndPort + ",suspend=y,server=y");
			injectVMArgs(commandLine);
			commandLine.add(getMainClassName());

			fLaunchedVM = exec(commandLine);

		} catch (IOException e) {
			throw new Error("Could not launch the VM because " + e.getMessage());
		}
	}
	/**
	 * Launches the target IBM VM.
	 */
	private void launchIBMTarget() {
		try {
			// Launch target VM
			String binDirectory =
				fTargetAddress
					+ File.separatorChar
					+ "bin"
					+ File.separatorChar;

			Vector<String> commandLine = new Vector<>();

			commandLine.add(binDirectory + "javaw");
			if (fBootPath.length() > 0) {
				commandLine.add("-bootpath");
				commandLine.add(fBootPath);
			}

			commandLine.add("-classpath");
			commandLine.add(fClassPath);
			commandLine.add("-Xdebug");
			commandLine.add("-Xnoagent");
			commandLine.add("-Djava.compiler=NONE");
			commandLine.add("-Xrunjdwp:transport=dt_socket,address=" + fBackEndPort + ",suspend=y,server=y");
			injectVMArgs(commandLine);
			commandLine.add(getMainClassName());

			fLaunchedVM = exec(commandLine);

		} catch (IOException e) {
			throw new Error("Could not launch the VM because " + e.getMessage());
		}
	}

	protected String getMainClassName() {
		return "org.eclipse.debug.jdi.tests.program.MainClass";
	}

	protected String getTestPrefix() {
		return "testJDI";
	}

	/**
	 * Injects arguments specified using -vmargs command line option into
	 * the provided commandLine.
	 * @param commandLine A vector of command line argument strings.
	 */
	private void injectVMArgs(Vector<String> commandLine) {
		if (fVmArgs != null) {
			String[] args = fVmArgs.split(",");
			for (int i=0; i < args.length; i++) {
				commandLine.add(args[i]);
			}
		}
	}

	/**
	 * Flattens the variable size command line and calls Runtime.exec().
	 * @param commandLine A vector of command line argument strings.
	 * @return The Process created by Runtime.exec()
	 * @throws IOException
	 */
	private Process exec(Vector<String> commandLine) throws IOException {
		String[] vmString = new String[commandLine.size()];
		commandLine.toArray(vmString);
		return Runtime.getRuntime().exec(vmString);
	}


	/**
	 * Connects to the target vm.
	 */
	protected void connectToVM() {
		// Start the console reader if possible so that the VM doesn't block when the stdout is full
		startConsoleReaders();


		// Contact the VM (try 10 times)
		for (int i = 0; i < 10; i++) {
			try {
				VirtualMachineManager manager = Bootstrap.virtualMachineManager();
				List<AttachingConnector> connectors = manager.attachingConnectors();
				if (connectors.size() == 0) {
					break;
				}
				AttachingConnector connector = connectors.get(0);
				Map<String, Argument> args = connector.defaultArguments();
				args.get("port").setValue(String.valueOf(fBackEndPort));
				args.get("hostname").setValue("localhost");

				fVM = connector.attach(args);
				if (fVMTraceFlags != com.sun.jdi.VirtualMachine.TRACE_NONE) {
					fVM.setDebugTraceMode(fVMTraceFlags);
				}
				break;
			} catch (IllegalConnectorArgumentsException e) {
			} catch (IOException e) {
//				System.out.println("Got exception: " + e.getMessage());
				try {
					if (i == 9) {
						System.out.println(
							"Could not contact the VM at localhost" + ":" + fBackEndPort + ".");
					}
					Thread.sleep(200);
				} catch (InterruptedException e2) {
				}
			}
		}
		if (fVM == null) {
			if (fLaunchedVM != null) {
				// If the VM is not running, output error stream
				try {
					if (!vmIsRunning()) {
						InputStream in = fLaunchedVM.getErrorStream();
						int read;
						do {
							read = in.read();
							if (read != -1) {
								System.out.print((char) read);
							}
						} while (read != -1);
					}
				} catch (IOException e) {
				}

				// Shut it down
				killVM();
			}
			throw new Error("Could not contact the VM");
		}
		startEventReader();
	}
	/**
	 * Initializes the fields that are used by this test only.
	 */
	public abstract void localSetUp();
	/**
	 * Makes sure the test leaves the VM in the same state it found it.
	 * Default is to do nothing.
	 */
	public void localTearDown() {
	}
	/**
	 * Parses the given arguments and store them in this tests
	 * fields.
	 * Returns whether the parsing was successful.
	 */
	protected static boolean parseArgs(String[] args) {
		// Default values
		String vmVendor = System.getProperty("java.vm.vendor");
		String vmVersion = System.getProperty("java.vm.version");
		String targetAddress = System.getProperty("java.home");
		String vmLauncherName;
		if (vmVendor != null
			&& (vmVendor.indexOf("Sun") > -1 || vmVendor.indexOf("Oracle") > -1 || vmVendor.indexOf("Apple") > -1)
			&& vmVersion != null) {
			vmLauncherName = "SunVMLauncher";
		} else if (
			vmVendor != null && vmVendor.indexOf("IBM") > -1 && vmVersion != null) {
			vmLauncherName = "IBMVMLauncher";
		} else {
			vmLauncherName = "J9VMLauncher";
		}
		String classPath = System.getProperty("java.class.path");
		String bootPath = "";
		String vmType = "?";
		boolean verbose = false;

		// Parse arguments
		for (int i = 0; i < args.length; ++i) {
			String arg = args[i];
			if (arg.startsWith("-")) {
				if (arg.equals("-verbose") || arg.equals("-v")) {
					verbose = true;
				} else {
					String next = (i < args.length - 1) ? args[++i] : null;
					// If specified, passed values override default values
					switch (arg) {
						case "-launcher":
							vmLauncherName = next;
							break;
						case "-address":
							targetAddress = next;
							break;
						case "-port":
							fBackEndPort = Integer.parseInt(next);
							break;
						case "-cp":
							classPath = next;
							break;
						case "-bp":
							bootPath = next;
							break;
						case "-vmtype":
							vmType = next;
							break;
						case "-stdout":
							fStdoutFile = next;
							break;
						case "-stderr":
							fStderrFile = next;
							break;
						case "-proxyout":
							fProxyoutFile = next;
							break;
						case "-proxyerr":
							fProxyerrFile = next;
							break;
						case "-vmcmd":
							fVmCmd = next;
							break;
						case "-vmargs":
							fVmArgs = next;
							break;
						case "-proxycmd":
							fProxyCmd = next;
							break;
						case "-trace":
							if (next.equals("all")) {
								fVMTraceFlags = com.sun.jdi.VirtualMachine.TRACE_ALL;
							} else {
								fVMTraceFlags = Integer.decode(next).intValue();
							}
							break;
						default:
							System.out.println("Invalid option: " + arg);
							printUsage();
							return false;
					}
				}
			}
		}
		fVMLauncherName = vmLauncherName;
		fTargetAddress = targetAddress;
		fClassPath = classPath;
		fBootPath = bootPath;
		fVMType = vmType;
		fVerbose = verbose;
		return true;
	}
	/**
	 * Prints the various options to pass to the constructor.
	 */
	protected static void printUsage() {
		System.out.println("Possible options:");
		System.out.println("-launcher <Name of the launcher class>");
		System.out.println("-address <Address of the target VM>");
		System.out.println("-port <Debug port number>");
		System.out.println("-cp <Path to the test program>");
		System.out.println("-bp <Boot classpath for the system class library>");
		System.out.println("-vmtype <The type of VM: JDK, J9, ...>");
		System.out.println("-verbose | -v");
		System.out.println("-stdout <file where VM output is written to>");
		System.out.println("-stderr <file where VM error output is written to>");
		System.out.println("-proxyout <file where proxy output is written to>");
		System.out.println("-proxyerr <file where proxy error output is written to>");
		System.out.println("-vmcmd <exec string to start VM>");
		System.out.println("-vmargs <comma-separated list of VM arguments>");
		System.out.println("-proxycmd <exec string to start proxy>");
	}
	/**
	 * Set the value of the "fBool" field back to its original value
	 */
	protected void resetField() {
		Field field = getField("fBool");
		Value value = null;
		value = fVM.mirrorOf(false);
		try {
			getObjectReference().setValue(field, value);
		} catch (ClassNotLoadedException e) {
			assertTrue("resetField.2", false);
		} catch (InvalidTypeException e) {
			assertTrue("resetField.3", false);
		}
	}
	/**
	 * Set the value of the "fString" field back to its original value
	 */
	protected void resetStaticField() {
		Field field = getField("fString");
		Value value = null;
		value = fVM.mirrorOf("Hello World");
		try {
			getMainClass().setValue(field, value);
		} catch (ClassNotLoadedException e) {
			assertTrue("resetField.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("resetField.2", false);
		}
	}
	/**
	 * Runs this test's suite with the given arguments.
	 */
	protected void runSuite(String[] args) {
		// Check args
		if (!parseArgs(args)) {
			return;
		}

		// Run test
		System.out.println(new java.util.Date());
		System.out.println("Begin testing " + getName() + "...");
		junit.textui.TestRunner.run(suite());
		System.out.println("Done testing " + getName() + ".");
	}
	/**
	 * Sets the 'in control of the VM' flag for this test.
	 */
	public void setInControl(boolean inControl) {
		fInControl = inControl;
	}
	/**
	 * Launch target VM and start program in target VM.
	 */
	protected void launchTargetAndStartProgram() {
		launchTargetAndConnectToVM();
		startProgram();
	}
	/**
	 * Init tests
	 */
	@Override
	protected void setUp() {
		if (fVM == null || fInControl) {
			launchTargetAndStartProgram();
		}
		try {
			verbose("Setting up the test");
			localSetUp();
		} catch (RuntimeException e) {
			System.out.println("Runtime exception during set up:");
			e.printStackTrace();
		} catch (Error e) {
			System.out.println("Error during set up:");
			e.printStackTrace();
		}
	}
	/**
	 * Sets the VM info for this test.
	 */
	public void setVMInfo(VMInformation info) {
		if (info != null) {
			fVM = info.fVM;
			fLaunchedVM = info.fLaunchedVM;
			fEventReader = info.fEventReader;
			fConsoleReader = info.fConsoleReader;
		}
	}
	/**
	 * Stop console and event readers.
	 */
	protected void stopReaders() {
		stopEventReader();
		stopConsoleReaders();
	}
	/**
	 * Shut down the target.
	 */
	public void shutDownTarget() {
		stopReaders();
		if (fVM != null) {
			try {
				fVM.exit(0);
			} catch (VMDisconnectedException e) {
			}
		}

		fVM = null;
		fLaunchedVM = null;

		// We want subsequent connections to use different ports, unless a
		// VM exec sting is given.
		if (fVmCmd == null) {
			fBackEndPort += 2;
		}
	}
	/**
	 * Starts the threads that reads from the VM and proxy input and error streams
	 */
	private void startConsoleReaders() {
		if (fStdoutFile != null) {
			fConsoleReader =
				new FileConsoleReader(
					"JDI Tests Console Reader",
					fStdoutFile,
					fLaunchedVM.getInputStream());
		} else {
			fConsoleReader =
				new NullConsoleReader("JDI Tests Console Reader", fLaunchedVM.getInputStream());
		}
		fConsoleReader.start();

		if (fStderrFile != null) {
			fConsoleErrorReader =
				new FileConsoleReader(
					"JDI Tests Console Error Reader",
					fStderrFile,
					fLaunchedVM.getErrorStream());
		} else {
			fConsoleErrorReader =
				new NullConsoleReader(
					"JDI Tests Console Error Reader",
					fLaunchedVM.getErrorStream());
		}
		fConsoleErrorReader.start();

		if (fLaunchedProxy == null) {
			return;
		}

		if (fProxyoutFile != null) {
			fProxyReader =
				new FileConsoleReader(
					"JDI Tests Proxy Reader",
					fProxyoutFile,
					fLaunchedProxy.getInputStream());
		} else {
			fProxyReader =
				new NullConsoleReader(
					"JDI Tests Proxy Reader",
					fLaunchedProxy.getInputStream());
		}
		fProxyReader.start();

		if (fProxyerrFile != null) {
			fProxyErrorReader =
				new FileConsoleReader(
					"JDI Tests Proxy Error Reader",
					fProxyerrFile,
					fLaunchedProxy.getErrorStream());
		} else {
			fProxyErrorReader =
				new NullConsoleReader(
					"JDI Tests Proxy Error Reader",
					fLaunchedProxy.getErrorStream());
		}
		fProxyErrorReader.start();
	}
	/**
	 * Stops the console reader.
	 */
	private void stopConsoleReaders() {
		if (fConsoleReader != null) {
			fConsoleReader.stop();
		}
		if (fConsoleErrorReader != null) {
			fConsoleErrorReader.stop();
		}
		if (fProxyReader != null) {
			fProxyReader.stop();
		}
		if (fProxyErrorReader != null) {
			fProxyErrorReader.stop();
		}
	}
	/**
	 * Starts event reader.
	 */
	private void startEventReader() {
		// Create the VM event reader.
		fEventReader = new EventReader("JDI Tests Event Reader", fVM.eventQueue());
	}
	/**
	 * Stops the event reader.
	 */
	private void stopEventReader() {
		fEventReader.stop();
	}
	protected void killVM() {
		if (fLaunchedVM != null) {
			fLaunchedVM.destroy();
		}
		if (fLaunchedProxy != null) {
			fLaunchedProxy.destroy();
		}
	}
	/**
	 * Starts the target program.
	 */
	protected void startProgram() {
		verbose("Starting target program");

		// Request class prepare events
		EventRequest classPrepareRequest =
			fVM.eventRequestManager().createClassPrepareRequest();
		classPrepareRequest.enable();

		// Prepare to receive the token class prepare event
		ClassPrepareEventWaiter waiter =
			new ClassPrepareEventWaiter(
				classPrepareRequest,
				true,
				getMainClassName());
		fEventReader.addEventListener(waiter);

		// Start the event reader (this will start the VM when the VMStartEvent is picked up)
		fEventReader.start();

		// Wait until the program has started
		Event event = waitForEvent(waiter, 3 * TIMEOUT);
		fEventReader.removeEventListener(waiter);
		if (event == null) {
//			try {
				System.out.println(
					"\nThe program doesn't seem to have started after " + (3 * TIMEOUT) + "ms");
//				InputStream errorStream = fLaunchedVM.getErrorStream();
//				int read;
//				do {
//					read = errorStream.read();
//					if (read != -1)
//						System.out.print((char) read);
//				} while (read != -1);
//			} catch (IOException e) {
//			}
		}

		// Stop class prepare events
		fVM.eventRequestManager().deleteEventRequest(classPrepareRequest);

		// Wait for the program to be ready to be tested
		waitUntilReady();
	}
	/**
	 * Returns all tests
	 */
	protected Test suite() {
		JDITestSuite suite = new JDITestSuite(this);
		Vector<String> testNames = getAllMatchingTests( getTestPrefix() );
		Iterator<String> iterator = testNames.iterator();
		while (iterator.hasNext()) {
			String name = iterator.next();
			suite.addTest(new JDITestCase(this, name));
		}
		return suite;
	}
	/**
	 * Undo the initialization of the test.
	 */
	@Override
	protected void tearDown() {
		try {
			super.tearDown();
		} catch (Exception e) {
			System.out.println("Exception during tear down:");
			e.printStackTrace();
		}
		try {
			verbose("Tearing down the test");
			localTearDown();

			// Ensure that the test didn't leave a modification watchpoint that could change the expected state of the program
			if (fVM != null) {
				assertTrue(fVM.eventRequestManager().modificationWatchpointRequests().isEmpty());
				if (fInControl) {
					shutDownTarget();
				}
			}

		} catch (RuntimeException e) {
			System.out.println("Runtime exception during tear down:");
			e.printStackTrace();
		} catch (Error e) {
			System.out.println("Error during tear down:");
			e.printStackTrace();
		}

	}
	/**
	 * Triggers and waits for the given event to come in.
	 * Let the thread go if asked.
	 * Throws an Error if the event didn't come in after TIMEOUT ms
	 */
	protected Event triggerAndWait(
		EventRequest request,
		String eventType,
		boolean shouldGo) {
		Event event = triggerAndWait(request, eventType, shouldGo, TIMEOUT);
		if (event == null) {
			throw new Error(
				"Event for " + request + " didn't come in after " + TIMEOUT + "ms");
		}

		return event;
	}
	/**
	 * Triggers and waits for the given event to come in.
	 * Let the thread go if asked.
	 * Returns null if the event didn't come in after the given amount of time (in ms)
	 * @param time the time to wait
	 */
	protected Event triggerAndWait(
		EventRequest request,
		String eventType,
		boolean shouldGo,
		long time) {
		// Suspend only if asked
		if (shouldGo) {
			request.setSuspendPolicy(EventRequest.SUSPEND_NONE);
		} else {
			request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
		}

		// Enable request
		request.enable();

		// Prepare to receive the event
		EventWaiter waiter = new EventWaiter(request, shouldGo);
		fEventReader.addEventListener(waiter);

		// Trigger the event
		triggerEvent(eventType);

		// Wait for the event to come in
		Event event = waitForEvent(waiter, TIMEOUT);
		fEventReader.removeEventListener(waiter);

		if (shouldGo) {
			// Wait for the program to be ready
			waitUntilReady();
		}

		// Clear request
		fVM.eventRequestManager().deleteEventRequest(request);

		return event;
	}
	/**
	 * Triggers the given type of event. See the MainClass for details on types of event.
	 */
	protected void triggerEvent(String eventType) {
		// Set the "fEventType" field to the given eventType
		ClassType type = getMainClass();
		Field field = type.fieldByName("fEventType");
		assertTrue("1", field != null);

		Value value = null;
		value = fVM.mirrorOf(eventType);
		try {
			type.setValue(field, value);
		} catch (ClassNotLoadedException e) {
			assertTrue("2", false);
		} catch (InvalidTypeException e) {
			assertTrue("3", false);
		}

		// Resume the test thread
		ThreadReference thread = getThread();
		int suspendCount = thread.suspendCount();
		for (int i = 0; i < suspendCount; i++) {
			thread.resume();
		}
	}
	/**
	 * Triggers a step event and waits for it to come in.
	 */
	protected StepEvent triggerStepAndWait() {
		return triggerStepAndWait(
			getThread(),
			StepRequest.STEP_MIN,
			StepRequest.STEP_OVER);
	}

	protected StepEvent triggerStepAndWait(
		ThreadReference thread,
		int gran,
		int depth) {
		// Request for step events
		EventRequest eventRequest =
			fVM.eventRequestManager().createStepRequest(thread, gran, depth);
		eventRequest.addCountFilter(1);
		eventRequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
		eventRequest.enable();

		return triggerStepAndWait(thread, eventRequest, TIMEOUT);
	}

	protected StepEvent triggerStepAndWait(
		ThreadReference thread,
		EventRequest eventRequest,
		int timeout) {
		// Prepare to receive the event
		EventWaiter waiter = new EventWaiter(eventRequest, true);
		fEventReader.addEventListener(waiter);

		// Trigger step event
		int suspendCount = thread.suspendCount();
		for (int i = 0; i < suspendCount; i++) {
			thread.resume();
		}

		// Wait for the event to come in
		StepEvent event = (StepEvent) waitForEvent(waiter, timeout);
		fEventReader.removeEventListener(waiter);
		if (event == null) {
			throw new Error("StepEvent didn't come in after " + timeout + "ms");
		}

		// Stop getting step events
		fVM.eventRequestManager().deleteEventRequest(eventRequest);

		// Wait for the program to be ready
		waitUntilReady();

		return event;
	}
	/**
	 * Output verbose string if asked for.
	 */
	protected void verbose(String verboseString) {
		if (fVerbose) {
			System.out.println(verboseString);
		}
	}
	/**
	 * Waits for an event to come in using the given waiter.
	 * Waits for the given time. If it times out, returns null.
	 */
	protected Event waitForEvent(EventWaiter waiter, long time) {
		Event event;
		try {
			event = waiter.waitEvent(time);
		} catch (InterruptedException e) {
			event = null;
		}
		return event;
	}
	/**
	 * Waits until the program is ready to be tested.
	 * The default behavior is to wait until the "Test Thread" throws and catches
	 * an exception.
	 */
	protected void waitUntilReady() {
		// Make sure the program is running
		ThreadReference thread = getThread();
		while (thread == null || thread.suspendCount() > 0) {
			fVM.resume();
			thread = getThread();
		}

		// Create exception request
		EventRequest request =
			fVM.eventRequestManager().createExceptionRequest(null, true, false);
		request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);

		// Prepare to receive the event
		EventWaiter waiter = new EventWaiter(request, false);
		fEventReader.addEventListener(waiter);

		request.enable();

		while (true) {
			// Wait for the event to come in
			ExceptionEvent event = (ExceptionEvent) waitForEvent(waiter, TIMEOUT);

			// Throw error if event is null
			if (event == null) {
				throw new Error("Target program was not ready after " + TIMEOUT + "ms");
			}

			// Get the method where the exception was thrown
			Method meth = event.location().method();
			if (meth == null || !meth.name().equals("printAndSignal")) {
				fVM.resume();
			} else {
				break;
			}
		}

		// Disable request
		fEventReader.removeEventListener(waiter);
		fVM.eventRequestManager().deleteEventRequest(request);
	}
}
