gt: 	LocalVirtualMachine localVM = super.launch();
context: /*******************************************************************************
   * Copyright (c) 2000, 2014 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.core.tests.runtime;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.Vector;
  
  import org.eclipse.jdt.core.tests.util.Util;
  
  /**
   * A J9 VM launcher launches an external J9 VM (and J9 Proxy if needed) with
   * the given arguments on the same machine.
   * <p>
   * Unlike with the <code>StandardVMLauncher</code>, a debugger would have to
   * connect to the J9 Proxy instead of connecting to the VM directly. In this case,
   * the Proxy port is the specified debug port. Note that an internal debug port
   * must also be specified. This port is used for the communication between the
   * Proxy and the VM.
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public class J9VMLauncher extends LocalVMLauncher {
  	int internalDebugPort = -1;
  	String proxyOutFile;
  	String symbolPath;
  /**
   * Creates a new J9VMLauncher that launches a J9 VM
   * (and J9 Proxy if needed) on the same machine.
   */
  public J9VMLauncher() {
  	super();
  }
  /**
   * Builds the actual boot class path that is going to be passed to the VM.
   */
  protected String buildBootClassPath() {
  	StringBuffer bootPathString = new StringBuffer();
  	char pathSeparator = File.pathSeparatorChar;
  
  	if (this.bootPath != null) {
  		// Add boot class path given by client
  		int length = this.bootPath.length;
  		for (int i = 0; i < length; i++){
  			bootPathString.append(this.bootPath[i]);
  			bootPathString.append(pathSeparator);
  		}
  	} else {
  		// Add regular classes.zip
  		bootPathString.append(this.vmPath);
  		bootPathString.append(File.separator);
  		bootPathString.append("lib");
  		bootPathString.append(File.separator);
  		bootPathString.append("jclMax");
  		bootPathString.append(File.separator);
  		bootPathString.append("classes.zip");
  		bootPathString.append(pathSeparator);
  	}
  
  	// Add boot class path directory if needed
  	if (this.evalTargetPath != null && TARGET_HAS_FILE_SYSTEM) {
  		bootPathString.append(this.evalTargetPath);
  		bootPathString.append(File.separatorChar);
  		bootPathString.append(BOOT_CLASSPATH_DIRECTORY);
  	}
  
  	return bootPathString.toString();
  }
  /**
   * @see LocalVMLauncher#execCommandLine
   */
  protected Process execCommandLine() throws TargetException {
  	// Check that the internal debug port has been specified if in debug mode
  	if (this.debugPort != -1 && this.internalDebugPort == -1) {
  		throw new TargetException("Internal debug port has not been specified");
  	}
  
  	return super.execCommandLine();
  }
  /**
   * @see LocalVMLauncher#getCommandLine
   */
  public String[] getCommandLine() {
  	Vector commandLine = new Vector();
  
  	// VM binary
  	commandLine.addElement(
  		this.vmPath +
  		(this.vmPath.endsWith(File.separator) ? "" : File.separator) +
  		"bin" +
  		File.separator +
  		"j9");
  
  	// VM arguments
  	if (this.vmArguments != null) {
  		for (int i = 0; i < this.vmArguments.length; i++) {
  			commandLine.addElement(this.vmArguments[i]);
  		}
  	}
  
  	// debug mode
  	if (this.debugPort != -1 && this.internalDebugPort != -1) {
  		commandLine.addElement("-debug:" + this.internalDebugPort);
  	}
  
  	// boot class path
  	commandLine.addElement("-Xbootclasspath:" + buildBootClassPath());
  
  	// regular class path
  	commandLine.addElement("-classpath");
  	commandLine.addElement(buildClassPath());
  
  	// code snippet runner class
  	if (this.evalPort != -1) {
  		commandLine.addElement(CODE_SNIPPET_RUNNER_CLASS_NAME);
  	}
  
  	// code snippet runner arguments
  	if (this.evalPort != -1) {
  		commandLine.addElement(EVALPORT_ARG);
  		commandLine.addElement(Integer.toString(this.evalPort));
  		if (TARGET_HAS_FILE_SYSTEM) {
  			commandLine.addElement(CODESNIPPET_CLASSPATH_ARG);
  			commandLine.addElement(this.evalTargetPath + File.separator + REGULAR_CLASSPATH_DIRECTORY);
  			commandLine.addElement(CODESNIPPET_BOOTPATH_ARG);
  			commandLine.addElement(this.evalTargetPath + File.separator + BOOT_CLASSPATH_DIRECTORY);
  		}
  	}
  
  	// program class
  	if (this.programClass != null) {
  		commandLine.addElement(this.programClass);
  	}
  
  	// program arguments
  	if (this.programArguments != null) {
  		for (int i=0;i<this.programArguments.length;i++) {
  			commandLine.addElement(this.programArguments[i]);
  		}
  	}
  
  	String[] result= new String[commandLine.size()];
  	commandLine.copyInto(result);
  
  	// check for spaces in result
  	for (int i = 0; i < result.length; i++) {
  		String argument = result[i];
  		if (argument.indexOf(' ') != -1) {
  			result[i] = "\"" + argument + "\"";
  		}
  	}
  
  	return result;
  }
  /**
   * Returns the debug port the J9 Proxy uses to connect to the J9 VM.
   * The value is unspecified if debug mode is disabled.
   * Note that the regular debug port is the port used to connect the J9 Proxy and
   * the IDE in the case of the J9 VM Launcher.
   */
  public int getInternalDebugPort() {
  	return this.internalDebugPort;
  }
  /**
   * Returns the command line which will be used to launch the Proxy.
   */
  public String[] getProxyCommandLine() {
  	Vector commandLine = new Vector();
  
  	// Proxy binary
  	commandLine.addElement(
  		this.vmPath +
  		(this.vmPath.endsWith(File.separator) ? "" : File.separator) +
  		"bin" +
  		File.separator +
  		"j9proxy");
  
  	// Arguments
  	commandLine.addElement(getTargetAddress() + ":" + this.internalDebugPort);
  	commandLine.addElement(Integer.toString(this.debugPort));
  	if (this.symbolPath != null && this.symbolPath != "") {
  		commandLine.addElement(this.symbolPath);
  	}
  
  	String[] result= new String[commandLine.size()];
  	commandLine.copyInto(result);
  	return result;
  }
  /**
   * Returns the full path name to the file where the proxy output is redirected.
   * Returns "con" if the proxy output is redirected to the stdout.
   * Returns null if the proxy output is not redirected.
   */
  public String getProxyOutFile() {
  	return this.proxyOutFile;
  }
  /**
   * Returns the full path name to the symbol file used by the J9 Proxy.
   * Returns null if the no symbol file is passed to the J9 Proxy.
   */
  public String getSymbolPath() {
  	return this.symbolPath;
  }
  /**
   * @see LocalVMLauncher#launch
   */
  public LocalVirtualMachine launch() throws TargetException {
  	// Launch VM
  