/*******************************************************************************
 * 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.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 junit.framework.Test;
import junit.framework.TestCase;

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;

/**
 * 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
					+ System.getProperty("file.separator")
					+ "bin"
					+ System.getProperty("file.separator");

			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(System.getProperty("file.separator"));
			binDirectory.append("bin").append(System.getProperty("file.separator"));

			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
					+ System.getProperty("file.separator")
					+ "bin"
					+ System.getProperty("file.separator");

			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
					if (arg.equals("-launcher")) {
						vmLauncherName = next;
					} else if (arg.equals("-address")) {
						targetAddress = next;
					} else if (arg.equals("-port")) {
						fBackEndPort = Integer.parseInt(next);
					} else if (arg.equals("-cp")) {
						classPath = next;
					} else if (arg.equals("-bp")) {
						bootPath = next;
					} else if (arg.equals("-vmtype")) {
						vmType = next;
					} else if (arg.equals("-stdout")) {
						fStdoutFile = next;
					} else if (arg.equals("-stderr")) {
						fStderrFile = next;
					} else if (arg.equals("-proxyout")) {
						fProxyoutFile = next;
					} else if (arg.equals("-proxyerr")) {
						fProxyerrFile = next;
					} else if (arg.equals("-vmcmd")) {
						fVmCmd = next;
					} else if (arg.equals("-vmargs")) {
						fVmArgs = next;
					} else if (arg.equals("-proxycmd")) {
						fProxyCmd = next;
					} else if (arg.equals("-trace")) {
						if (next.equals("all")) {
							fVMTraceFlags = com.sun.jdi.VirtualMachine.TRACE_ALL;
						} else {
							fVMTraceFlags = Integer.decode(next).intValue();
						}
					} else {
						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().size() == 0);
				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);
	}
}
