/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.launcher;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Startup class for Eclipse. Creates a class loader using
 * supplied URL of platform installation, loads and calls
 * the Eclipse Boot Loader.  The startup arguments are as follows:
 * <dl>
 * <dd>
 *    -application &lt;id&gt;: the identifier of the application to run
 * </dd>
 * <dd>
 *    -arch &lt;architecture&gt;: sets the processor architecture value
 * </dd>
 * <dd>
 *    -boot &lt;location&gt;: the location, expressed as a URL, of the platform's boot.jar.
 * <i>Deprecated: replaced by -configuration</i>
 * </dd>
 * <dd>
 *    -classloaderproperties [properties file]: activates platform class loader enhancements using 
 * the class loader properties file at the given location, if specified. The (optional) file argument 
 * can be either a file path or an absolute URL.
 * </dd>
 * <dd>
 *    -configuration &lt;location&gt;: the location, expressed as a URL, for the Eclipse platform 
 * configuration file. The configuration file determines the location of the Eclipse platform, the set 
 * of available plug-ins, and the primary feature.
 * </dd>
 * <dd>
 *    -consolelog : enables log to the console. Handy when combined with -debug
 * </dd>
 * <dd>
 *    -data &lt;location&gt;: sets the workspace location and the default location for projects
 * </dd>
 * <dd>
 *    -debug [options file]: turns on debug mode for the platform and optionally specifies a location
 * for the .options file. This file indicates what debug points are available for a
 * plug-in and whether or not they are enabled. If a location is not specified, the platform searches
 * for the .options file under the install directory.
 * </dd>
 * <dd>
 *    -dev [entries]: turns on dev mode and optionally specifies comma-separated class path entries
 * which are added to the class path of each plug-in
 * </dd>
 * <dd>
 *    -feature &lt;id&gt;: the identifier of the primary feature. The primary feature gives the launched 
 * instance of Eclipse its product personality, and determines the product customization 
 * information.
 * </dd>
 * <dd>
 *    -keyring &lt;location&gt;: the location of the authorization database on disk. This argument
 * has to be used together with the -password argument.
 * </dd>
 * <dd>
 *    -nl &lt;locale&gt;: sets the name of the locale on which Eclipse platform will run
 * </dd>
 * <dd>
 *    -nolazyregistrycacheloading : deactivates platform plug-in registry cache loading optimization. 
 * By default, extensions' configuration elements will be loaded from the registry cache (when 
 * available) only on demand, reducing memory footprint. This option will force the registry cache 
 * to be fully loaded at startup.
 * </dd>
 *  <dd>
 *    -nopackageprefixes: deactivates classloader package prefixes optimization
 * </dd> 
 *  <dd>
 *    -noregistrycache: bypasses the reading and writing of an internal plug-in registry cache file
 * </dd>
 * <dd>
 *    -os &lt;operating system&gt;: sets the operating system value
 * </dd>
 * <dd>
 *    -password &lt;passwd&gt;: the password for the authorization database
 * </dd>
 * <dd>
 *    -plugins &lt;location&gt;: the arg is a URL pointing to a file which specs the plugin 
 * path for the platform.  The file is in property file format where the keys are user-defined 
 * names and the values are comma separated lists of either explicit paths to plugin.xml 
 * files or directories containing plugins (e.g., .../eclipse/plugins). 
 * <i>Deprecated: replaced by -configuration</i>
 * </dd>
 * <dd>
 *    -plugincustomization &lt;properties file&gt;: the location of a properties file containing default 
 * settings for plug-in preferences. These default settings override default settings specified in the 
 * primary feature. Relative paths are interpreted relative to the directory that eclipse was started 
 * from.
 * </dd> 
 * <dd>
 *    -ws &lt;window system&gt;: sets the window system value
 * </dd>
 * </dl>
 */
public class Main {
	/**
	 * Indicates whether this instance is running in debug mode.
	 */
	protected boolean debug = false;
	
	/**
	 * The location of the launcher to run.
	 */
	protected String bootLocation = null;
	
	/**
	 * The location of the install root
	 */
	protected String rootLocation = null;
	
	/**
	 * The identifier of the application to run.
	 */
	protected String application;
	
	/**
	 * The identifier of the feature to run.
	 */
	protected String feature;
	
	/**
	 * The identifier of the configuration to use.
	 */
	protected String configuration;
	
	/**
	 * The path for finding find plugins.
	 */
	protected URL pluginPathLocation;
	
	/**
	 * The boot path location.
	 */
	protected String location;		
		
	/**
	 * The class path entries.
	 */
	protected String devClassPath = null;
	
	/**
	 * Indicates whether this instance is running in development mode.
	 */
	protected boolean inDevelopmentMode = false;

	// splash handling
	private String showSplash = null; 
	private String endSplash = null; 
	private boolean cmdInitialize = false;
	private boolean cmdFirstUse = false;
	private Process showProcess = null;
	private boolean splashDown = false; 
	private final Runnable endSplashHandler = new Runnable() {
		public void run() {
			takeDownSplash();
		}
	}; 
	
	// configuration properties
	private Properties props = new Properties();
	private HashMap featureIndex = new HashMap();
	private String baseLocation = null;
	
	// constants
	private static final String APPLICATION = "-application"; //$NON-NLS-1$
	private static final String BOOT = "-boot"; //$NON-NLS-1$
	private static final String INSTALL = "-install"; //$NON-NLS-1$
	private static final String INITIALIZE = "-initialize"; //$NON-NLS-1$
	private static final String DEBUG = "-debug"; //$NON-NLS-1$
	private static final String DEV = "-dev"; //$NON-NLS-1$
	private static final String DATA = "-data"; //$NON-NLS-1$
	private static final String CONFIGURATION = "-configuration"; //$NON-NLS-1$
	private static final String FEATURE = "-feature"; //$NON-NLS-1$
	private static final String SHOWSPLASH = "-showsplash"; //$NON-NLS-1$
	private static final String ENDSPLASH = "-endsplash"; //$NON-NLS-1$
	private static final String FIRST_USE = "-firstuse"; //$NON-NLS-1$
	private static final String SPLASH_IMAGE = "splash.bmp"; //$NON-NLS-1$
	private static final String PI_BOOT = "org.eclipse.core.boot"; //$NON-NLS-1$
	private static final String BOOTLOADER = "org.eclipse.core.boot.BootLoader"; //$NON-NLS-1$
	private static final String BOOTJAR = "boot.jar"; //$NON-NLS-1$
	private static final String PLATFORM_URL = "platform:/base/"; //$NON-NLS-1$
	
	// constants: configuration file location
	private static final String CONFIG_FILE = "platform.cfg"; //$NON-NLS-1$
	private static final String CONFIG_FILE_TEMP_SUFFIX = ".tmp"; //$NON-NLS-1$
	private static final String CONFIG_FILE_BAK_SUFFIX = ".bak"; //$NON-NLS-1$
	private static final String ARG_USER_DIR = "user.dir"; //$NON-NLS-1$
	
	// constants: configuration file elements
	private static final String CFG_CORE_BOOT = "bootstrap." + PI_BOOT;  //$NON-NLS-1$
	private static final String CFG_FEATURE_ENTRY = "feature"; //$NON-NLS-1$
	private static final String CFG_FEATURE_ENTRY_DEFAULT = "feature.default.id"; //$NON-NLS-1$
	private static final String CFG_FEATURE_ENTRY_ID = "id"; //$NON-NLS-1$
	private static final String CFG_FEATURE_ENTRY_ROOT = "root"; //$NON-NLS-1$
	private static final String CFG_EOF = "eof"; //$NON-NLS-1$

	// log file handling
	protected static final String SESSION = "!SESSION"; //$NON-NLS-1$
	protected static final String ENTRY = "!ENTRY"; //$NON-NLS-1$
	protected static final String MESSAGE = "!MESSAGE"; //$NON-NLS-1$
	protected static final String STACK = "!STACK"; //$NON-NLS-1$
	protected static final int ERROR = 4;
	protected static final String PLUGIN_ID = "org.eclipse.core.launcher"; //$NON-NLS-1$
	protected static File logFile = null;
	protected static BufferedWriter log = null;
	protected static String[] arguments;
	protected static boolean newSession = true;

	static class Identifier {
		private static final String DELIM = ". "; //$NON-NLS-1$
		private int major, minor, service;
		private Identifier(int major, int minor, int service) {
			super();
			this.major = major;
			this.minor = minor;
			this.service = service;
		}
		private Identifier(String versionString) {
			super();
			StringTokenizer tokenizer = new StringTokenizer(versionString, DELIM);
			
			// major
			if (tokenizer.hasMoreTokens())
				major = Integer.parseInt(tokenizer.nextToken());

			// minor
			if (tokenizer.hasMoreTokens())
				minor = Integer.parseInt(tokenizer.nextToken());

			// service
			if (tokenizer.hasMoreTokens())
				service = Integer.parseInt(tokenizer.nextToken());
		}
		/**
		 * Returns true if this id is considered to be greater than or equal to the given baseline.
		 * e.g. 
		 * 1.2.9 >= 1.3.1 -> false
		 * 1.3.0 >= 1.3.1 -> false
		 * 1.3.1 >= 1.3.1 -> true
		 * 1.3.2 >= 1.3.1 -> true
		 * 2.0.0 >= 1.3.1 -> true
		 */
		private boolean isGreaterEqualTo(Identifier minimum) {
			if (major < minimum.major)
				return false;
			if (major > minimum.major)
				return true;
			// major numbers are equivalent so check minor
			if (minor < minimum.minor)
				return false;
			if (minor > minimum.minor)
				return true;
			// minor numbers are equivalent so check service
			return service >= minimum.service;
		}
	}
/**
 * Executes the launch.
 * 
 * @return the result of performing the launch
 * @param args command-line arguments
 * @exception Exception thrown if a problem occurs during the launch
 */
protected Object basicRun(String[] args) throws Exception {
	// locate boot plugin (may return -dev mode variations)
	URL[] bootPath = getBootPath(bootLocation);
	
	// splash handling is done here, because the default case needs to know
	// the location of the boot plugin we are going to use
	handleSplash(bootPath);
	
	// load the BootLoader and startup the platform
	Class clazz = getBootLoader(bootPath);
	Method method = clazz.getDeclaredMethod("run", new Class[] { String.class, URL.class, String.class, String[].class, Runnable.class }); //$NON-NLS-1$
	try {
		return method.invoke(clazz, new Object[] { application, pluginPathLocation, location, args, endSplashHandler });
	} catch (InvocationTargetException e) {
		if (e.getTargetException() instanceof Error)
			throw (Error) e.getTargetException();
		else
			throw e;
	}
}
/**
 * Returns a string representation of the given URL String.  This converts
 * escaped sequences (%..) in the URL into the appropriate characters.
 * NOTE: due to class visibility there is a copy of this method
 *       in InternalBootLoader
 */
protected String decode(String urlString) {
	//try to use Java 1.4 method if available
	try {
		Class clazz = URLDecoder.class;
		Method method = clazz.getDeclaredMethod("decode", new Class[] {String.class, String.class});//$NON-NLS-1$
		//first encode '+' characters, because URLDecoder incorrectly converts 
		//them to spaces on certain class library implementations.
		if (urlString.indexOf('+') >= 0) {
			int len = urlString.length();
			StringBuffer buf = new StringBuffer(len);
			for (int i = 0; i < len; i++) {
				char c = urlString.charAt(i);
				if (c == '+')
					buf.append("%2B");//$NON-NLS-1$
				else
					buf.append(c);
			}
			urlString = buf.toString();
		}
		Object result = method.invoke(null, new Object[] {urlString, "UTF-8"});//$NON-NLS-1$
		if (result != null)
			return (String)result;
	} catch (Exception e) {
		//JDK 1.4 method not found -- fall through and decode by hand
	}
	//decode URL by hand
	boolean replaced = false;
	byte[] encodedBytes = urlString.getBytes();
	int encodedLength = encodedBytes.length;
	byte[] decodedBytes = new byte[encodedLength];
	int decodedLength = 0;
	for (int i = 0; i < encodedLength; i++) {
		byte b = encodedBytes[i];
		if (b == '%') {
			byte enc1 = encodedBytes[++i];
			byte enc2 = encodedBytes[++i];
			b = (byte) ((hexToByte(enc1) << 4) + hexToByte(enc2));
			replaced = true;
		}
		decodedBytes[decodedLength++] = b;
	}
	if (!replaced)
		return urlString;
	try {
		return new String(decodedBytes, 0, decodedLength, "UTF-8");//$NON-NLS-1$
	} catch (UnsupportedEncodingException e) {
		//use default encoding
		return new String(decodedBytes, 0, decodedLength);
	}
}
/**
 * Returns the result of converting a list of comma-separated tokens into an array
 * 
 * @return the array of string tokens
 * @param prop the initial comma-separated string
 */
private String[] getArrayFromList(String prop) {
	if (prop == null || prop.trim().equals("")) //$NON-NLS-1$
		return new String[0];
	Vector list = new Vector();
	StringTokenizer tokens = new StringTokenizer(prop, ","); //$NON-NLS-1$
	while (tokens.hasMoreTokens()) {
		String token = tokens.nextToken().trim();
		if (!token.equals("")) //$NON-NLS-1$
			list.addElement(token);
	}
	return list.isEmpty() ? new String[0] : (String[]) list.toArray(new String[0]);
}
/**
 * Creates and returns a platform <code>BootLoader</code> which can be used to start
 * up and run the platform.  
 * 
 * @return the new boot loader
 * @param path search path for the BootLoader
 */
public Class getBootLoader(URL[] path) throws Exception {
	URLClassLoader loader = new URLClassLoader(path, null);
	return loader.loadClass(BOOTLOADER);
}
/**
 * Returns the <code>URL</code>-based class path describing where the boot classes
 * are located when running in development mode.
 * 
 * @return the url-based class path
 * @param base the base location
 * @exception MalformedURLException if a problem occurs computing the class path
 */
protected URL[] getDevPath(URL base) throws MalformedURLException {
	URL url;
	String devBase = base.toExternalForm();
	if (!inDevelopmentMode) {
		url = new URL(devBase + BOOTJAR);
		return new URL[] {url};
	}
	String[] locations = getArrayFromList(devClassPath);
	ArrayList result = new ArrayList(locations.length);
	for (int i = 0; i < locations.length; i++) {
		String spec = devBase + locations[i];
		char lastChar = spec.charAt(spec.length() - 1);
		if ((spec.endsWith(".jar") || (lastChar == '/' || lastChar == '\\'))) //$NON-NLS-1$
			url = new URL (spec);
		else
			url = new URL(spec + "/"); //$NON-NLS-1$
		//make sure URL exists before adding to path
		if (new java.io.File(url.getFile()).exists())
			result.add(url);
	}
	url = new URL(devBase + BOOTJAR);
	if (new java.io.File(url.getFile()).exists())
		result.add(url);
	return (URL[])result.toArray(new URL[result.size()]);
}

/**
 * Returns the <code>URL</code>-based class path describing where the boot classes are located.
 * 
 * @return the url-based class path
 * @param base the base location
 * @exception MalformedURLException if a problem occurs computing the class path
 */
protected URL[] getBootPath(String base) throws MalformedURLException {
	URL url = null;
	// if the given location is not null, assume it is correct and use it. 
	if (base != null) {
		url = new URL(base);
		if (debug)
			System.out.println("Boot URL: " + url.toExternalForm()); //$NON-NLS-1$
		return new URL[] {url};	
	}
	// search for boot in root location
	URL[] result = null;
	url = new URL(rootLocation);
	String path = url.getFile();
	path = searchForBoot(path);
	// add on any dev path elements
	url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
	result = getDevPath(url);
	if (debug) {
		System.out.println("Boot URL:"); //$NON-NLS-1$
		for (int i = 0; i < result.length; i++)
			System.out.println("    " + result[i].toExternalForm()); //$NON-NLS-1$
	}
	return result;
}

/**
 * Searches for a boot directory starting in the "plugins" subdirectory
 * of the given location.  If one is found then this location is returned; 
 * otherwise an exception is thrown.
 * 
 * @return the location where boot directory was found
 * @param start the location to begin searching at
 */
protected String searchForBoot(String start) {
	FileFilter filter = new FileFilter() {
		public boolean accept(File candidate) {
			return candidate.isDirectory() &&
				(candidate.getName().equals(PI_BOOT)
				|| candidate.getName().startsWith(PI_BOOT + "_")); //$NON-NLS-1$
		}
	};
	File[] boots = new File(start, "plugins").listFiles(filter); //$NON-NLS-1$
	if (boots == null)
		throw new RuntimeException("Could not find bootstrap code. Check location of boot plug-in or specify -boot."); //$NON-NLS-1$
	String result = null;
	Object maxVersion = null;
	for (int i = 0; i < boots.length; i++) {
		String name = boots[i].getName();
		int index = name.indexOf('_');
		String version;
		Object currentVersion;
		if (index == -1)
			version = "";  //$NON-NLS-1$ // Note: directory with version suffix is always > than directory without version suffix
		else
			version = name.substring(index + 1);
		currentVersion = getVersionElements(version);			
		if (maxVersion == null) {
			result = boots[i].getAbsolutePath();
			maxVersion = currentVersion;
		} else {
			if (compareVersion((Object[])maxVersion, (Object[])currentVersion) < 0) {
				result = boots[i].getAbsolutePath();
				maxVersion = currentVersion;
			}
		}
	}
	if (result == null)
		throw new RuntimeException("Could not find bootstrap code. Check location of boot plug-in or specify -boot."); //$NON-NLS-1$
	return result.replace(File.separatorChar, '/') + "/"; //$NON-NLS-1$
}

/**
 * Compares version strings. 
 * @return result of comparison, as integer;
 * <code><0</code> if left < right;
 * <code>0</code> if left == right;
 * <code>>0</code> if left > right;
 */
private int compareVersion(Object[] left, Object[] right) {
	
	int result = ((Integer)left[0]).compareTo((Integer)right[0]); // compare major
	if (result != 0)
		return result;
		
	result = ((Integer)left[1]).compareTo((Integer)right[1]); // compare minor
	if (result != 0)
		return result;
		
	result = ((Integer)left[2]).compareTo((Integer)right[2]); // compare service
	if (result != 0)
		return result;
		
	return ((String)left[3]).compareTo((String)right[3]); // compare qualifier
}

/**
 * Do a quick parse of version identifier so its elements can be correctly compared.
 * If we are unable to parse the full version, remaining elements are initialized
 * with suitable defaults.
 * @return an array of size 4; first three elements are of type Integer (representing
 * major, minor and service) and the fourth element is of type String (representing
 * qualifier). Note, that returning anything else will cause exceptions in the caller.
 */
private Object[] getVersionElements(String version) {
	Object[] result = {new Integer(0), new Integer(0), new Integer(0), ""}; //$NON-NLS-1$
	StringTokenizer t = new StringTokenizer(version, "."); //$NON-NLS-1$
	String token;
	int i = 0;
	while(t.hasMoreTokens() && i<4) {
		token = t.nextToken();
		if (i<3) {
			// major, minor or service ... numeric values
			try {
				result[i++] = new Integer(token);
			} catch(Exception e) {
				// invalid number format - use default numbers (0) for the rest
				break; 
			}
		} else {
			// qualifier ... string value
			result[i++] = token;
		}
	}
	return result;
}

/**
 * Runs the platform with the given arguments.  The arguments must identify
 * an application to run (e.g., <code>-application com.example.application</code>).
 * After running the application <code>System.exit(N)</code> is executed.
 * The value of N is derived from the value returned from running the application.
 * If the application's return value is an <code>Integer</code>, N is this value.
 * In all other cases, N = 0.
 * <p>
 * Clients wishing to run the platform without a following <code>System.exit</code>
 * call should use <code>run()</code>.
 *
 * @see #run
 * 
 * @param args the command line arguments
 */
public static void main(String[] args) {
	Object result = null;
	arguments = args;
	// Check to see if we are running with a compatible VM.
	// If not, then return exit code "14" which will be recognized
	// by the executable and an appropriate message will be displayed
	// to the user.
	if (!isCompatible())
		System.exit(14);
	// Check to see if there is already a platform running in
	// this workspace. If there is, then return an exit code of "15" which
	// will be recognized by the executable and an appropriate message
	// will be displayed to the user.
	if (isAlreadyRunning())
		System.exit(15);
	Main launcher = new Main();
	try {
		result = launcher.run(args);
	} catch (Throwable e) {
		// try and take down the splash screen.
		launcher.takeDownSplash();
		log("Exception launching the Eclipse Platform:"); //$NON-NLS-1$
		log(e);
		// Return "unlucky" 13 as the exit code. The executable will recognize
		// this constant and display a message to the user telling them that
		// there is information in their log file.
		System.exit(13);
	}
	int exitCode = result instanceof Integer ? ((Integer) result).intValue() : 0;
	System.exit(exitCode);
}

/**
 * Runs this launcher with the arguments specified in the given string.
 * 
 * @param argString the arguments string
 * @exception Exception thrown if a problem occurs during launching
 */
public static void main(String argString) throws Exception {
	Vector list = new Vector(5);
	for (StringTokenizer tokens = new StringTokenizer(argString, " "); tokens.hasMoreElements();) //$NON-NLS-1$
		list.addElement((String) tokens.nextElement());
	main((String[]) list.toArray(new String[list.size()]));
}

/**
 * Processes the command line arguments
 * 
 * @return the arguments to pass through to the launched application
 * @param args the command line arguments
 */
protected String[] processCommandLine(String[] args) throws Exception {
	int[] configArgs = new int[100];
	configArgs[0] = -1; // need to initialize the first element to something that could not be an index.
	int configArgIndex = 0;
	for (int i = 0; i < args.length; i++) {
		boolean found = false;
		// check for args without parameters (i.e., a flag arg)
		// check if debug should be enabled for the entire platform
		if (args[i].equalsIgnoreCase(DEBUG)) {
			debug = true;
			// passed thru this arg (i.e., do not set found = true
			continue;
		}
		
		// check if this is initialization pass
		if (args[i].equalsIgnoreCase(INITIALIZE)) {
			cmdInitialize = true;
			// passed thru this arg (i.e., do not set found = true
			continue;
		}
		
		// check if development mode should be enabled for the entire platform
		// If this is the last arg or there is a following arg (i.e., arg+1 has a leading -), 
		// simply enable development mode.  Otherwise, assume that that the following arg is
		// actually some additional development time class path entries.  This will be processed below.
		if (args[i].equalsIgnoreCase(DEV) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) { //$NON-NLS-1$
			inDevelopmentMode = true;
			// do not mark the arg as found so it will be passed through
			continue;
		}

		// done checking for args.  Remember where an arg was found 
		if (found) {
			configArgs[configArgIndex++] = i;
			continue;
		}
		// check for args with parameters. If we are at the last argument or if the next one
		// has a '-' as the first character, then we can't have an arg with a parm so continue.
		if (i == args.length - 1 || args[i + 1].startsWith("-"))  //$NON-NLS-1$
			continue;
		String arg = args[++i];

		// look for the laucher to run
		if (args[i - 1].equalsIgnoreCase(BOOT)) {
			bootLocation = arg;
			found = true;
		}

		// look explicitly set install root
		if (args[i - 1].equalsIgnoreCase(INSTALL)) {
			rootLocation = arg;
			found = true;
		}

		// look for the development mode and class path entries.  
		if (args[i - 1].equalsIgnoreCase(DEV)) {
			inDevelopmentMode = true;
			devClassPath = arg;
			continue;
		}

		// look for the location of workspace
		if (args[i - 1].equalsIgnoreCase(DATA)) {
			baseLocation = arg;
			continue; // pass the arg on
		}

		// look for the application to run
		if (args[i - 1].equalsIgnoreCase(APPLICATION)) {
			application = arg;
			found = true;
		}

		// look for the feature to run
		if (args[i - 1].equalsIgnoreCase(FEATURE)) {
			feature = arg;
			continue; // pass the arg on [20063]
		}

		// look for the configuration to use
		if (args[i - 1].equalsIgnoreCase(CONFIGURATION)) {
			configuration = arg;
			// we  mark -configuration for removal. It will be
			// reinserted after we determine the actual URL of
			// the configuration file to use.
			found = true;
		}

		// look for token to use to show the splash screen
		if (args[i - 1].equalsIgnoreCase(SHOWSPLASH)) {
			showSplash = arg;
			found = true;
		}

		// look for token to use to end the splash screen
		if (args[i - 1].equalsIgnoreCase(ENDSPLASH)) {
			endSplash = arg;
			found = true;
		}

		// done checking for args.  Remember where an arg was found 
		if (found) {
			configArgs[configArgIndex++] = i - 1;
			configArgs[configArgIndex++] = i;
		}
	}
	// remove all the arguments consumed by this argument parsing
	if (configArgIndex == 0)
		return args;
	String[] passThruArgs = new String[args.length - configArgIndex];
	configArgIndex = 0;
	int j = 0;
	for (int i = 0; i < args.length; i++) {
		if (i == configArgs[configArgIndex])
			configArgIndex++;
		else
			passThruArgs[j++] = args[i];
	}
	return passThruArgs;
}
/**
 * Runs the application to be launched.
 * 
 * @return the return value from the launched application
 * @param args the arguments to pass to the application
 * @exception thrown if a problem occurs during launching
 */
public Object run(String[] args) throws Exception {
	String[] passThruArgs = processCommandLine(args);
	passThruArgs = processConfiguration(passThruArgs);
	return basicRun(passThruArgs);
}

/*
 * After the command line arguments have been processed, we try
 * to locate and load the platform configuration file. It contains
 * information maintained by the install/ update support. In 
 * particular, the following are needed at this point
 * in the startup sequence:
 * -> if -boot was not specified, which boot.jar to load 
 *    BootLoader from (original core.boot plugin may have been updated)
 * -> if -feature was not specified, what is the default feature
 *    (product packagers can set the default)
 * -> if we were requested to put up the splash (-showsplash
 *    was specified), which one (based on defaulted or
 *    specified feature information)
 * Note, that if we can't find the platform configuration file,
 * or it does not contain the information we are looking for,
 * the startup support ends up computing "reasonable" defaults
 * as before (based on relative locations within the file system)
 */
private String[] processConfiguration(String[] passThruArgs) throws MalformedURLException {
	// get install root location, if not specified
	if (rootLocation == null)
		rootLocation = getRootURL().toExternalForm();
		
	// attempt to locate configuration file
	URL configURL = null;
	if (configuration != null && !configuration.trim().equals("")) { //$NON-NLS-1$
		configuration = configuration.replace(File.separatorChar, '/');
		if (configuration.equalsIgnoreCase(ARG_USER_DIR)) {
			// configuration is in current working directory
			String tmp = System.getProperty("user.dir"); //$NON-NLS-1$
			if (!tmp.endsWith(File.separator))
				tmp += File.separator;
			configURL = new URL("file:" + tmp.replace(File.separatorChar,'/') + CONFIG_FILE); //$NON-NLS-1$
		} else if(configuration.endsWith("/")) { //$NON-NLS-1$
			// configuration specified as directory URL		
			configURL = new URL(configuration + CONFIG_FILE);
		} else {
			// configuration specified down to a file			
			configURL = new URL(configuration);
		}
	} else {
		// configuration not specified - defer to BootLoader
	}
		
	// load configuration
	loadConfiguration(configURL);
	
	// get boot url, if none was specified
	if (bootLocation == null) {
		String urlString = loadAttribute(props, CFG_CORE_BOOT, null);
		if (urlString != null) {
			try {
				urlString = resolve(urlString);
				URL bootDir = new URL(urlString);
				URL bootURL = new URL(bootDir, BOOTJAR);
				if (bootDir.getProtocol().equals("file")) { //$NON-NLS-1$
					File jar = new File(bootURL.getFile());
					if (jar.exists())
						// verify boot dir exists
						bootLocation = bootURL.toExternalForm();
					else
						// Somebody turned the tables on us. The info in
						// platform.cfg is stale, or the workspace is being used
						// with a new install. Do default search for boot and force
						// "first use" processing (optimistic reconciliation)
						cmdFirstUse = true;
				} else
					bootLocation = bootURL.toExternalForm();
			} catch(MalformedURLException e) {
				// continue ... will do default search for boot
			}
		}
	}
		
	// reconstruct command line arguments for configuration elements
	// (-boot and -application are not passed to BootLoader)
	if (configURL == null && rootLocation == null)
		return passThruArgs;
			
	ArrayList args = new ArrayList(Arrays.asList(passThruArgs));
	
	if (configURL != null) {
		args.add(CONFIGURATION);
		args.add(decode(configURL.toExternalForm()));
	}
	
	if (cmdFirstUse) {
		args.add(FIRST_USE);
	}
	
	// pass root location downstream
	if (rootLocation != null) {
		args.add(INSTALL);
		args.add(rootLocation);
	}
	
	return (String[])args.toArray(new String[0]);
}

/**
 * Returns url of the location this class was loaded from
 */
private URL getRootURL() throws MalformedURLException {
	if (rootLocation != null)
		return new URL(rootLocation);
		
	URL	url = getClass().getProtectionDomain().getCodeSource().getLocation();
	String path = decode(url.getFile());
	path = new File(path).getAbsolutePath().replace(File.separatorChar,'/');
	if (path.endsWith(".jar")) //$NON-NLS-1$
		path = path.substring(0, path.lastIndexOf("/")+1); //$NON-NLS-1$
	url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
	rootLocation = url.toExternalForm();
	return url;
}

/*
 * Load the configuration file. If not specified, default to the workspace
 */
private void loadConfiguration(URL url) {
	if (url == null) {
		// configuration URL was not specified ..... search
		String base = baseLocation;
		if (base == null) {
			// determine default workspace
			base = System.getProperty("user.dir"); //$NON-NLS-1$
			if (!base.endsWith(File.separator))
				base += File.separator;
			base += "workspace" + File.separator; //$NON-NLS-1$
		} else {
			base = base.replace('/',File.separatorChar);
		}
		if (!base.endsWith(File.separator))
			base += File.separator;
		
		File cfg = null;	
		try {
			// first look for configuration in base location (workspace or as specified)
			cfg = new File(base + ".metadata" + File.separator + ".config" + File.separator + CONFIG_FILE); //$NON-NLS-1$ //$NON-NLS-2$
			url = new URL("file", null, 0, cfg.getAbsolutePath()); //$NON-NLS-1$
			props = loadProperties(url);
			if (debug)
				System.out.println("Startup: using configuration " + url.toString()); //$NON-NLS-1$
			return; // we're done looking
		} catch(IOException e) {
			// continue ...
		}
		
		try {
			// look for configuration in install root (set up by -initialize)
			String install = getRootURL().getFile().replace('/',File.separatorChar);
			if (!install.endsWith(File.separator))
				install += File.separator;
			cfg = new File(install + ".config" + File.separator + CONFIG_FILE); //$NON-NLS-1$
			url = new URL("file", null, 0, cfg.getAbsolutePath()); //$NON-NLS-1$
			props = loadProperties(url);
			if (debug)
				System.out.println("Startup: using configuration " + url.toString()); //$NON-NLS-1$
		} catch(IOException e) {
			// continue ...
			if (debug)
				System.out.println("Startup: unable to load configuration\n" + e); //$NON-NLS-1$
		}
	} else {
		try {
			// configuration url was specified ... use it
			props = loadProperties(url);
			if (debug)
				System.out.println("Startup: using configuration " + url.toString()); //$NON-NLS-1$
		} catch(IOException e) {
			// continue ...
			if (debug)
				System.out.println("Startup: unable to load configuration\n" + e); //$NON-NLS-1$
		}
	}
}

private Properties loadProperties(URL url) throws IOException {
		
	// try to load saved configuration file (watch for failed prior save())
	Properties props = null;
	IOException originalException = null;
	try {
		props = load(url, null); // try to load config file
	} catch(IOException e1) {
		originalException = e1;
		try {
			props = load(url, CONFIG_FILE_TEMP_SUFFIX); // check for failures on save
		} catch(IOException e2) {
			try {
				props = load(url, CONFIG_FILE_BAK_SUFFIX); // check for failures on save
			} catch(IOException e3) {
				throw originalException; // we tried, but no config here ...
			}
		}
	}
	
	return props;
}
 
/*
 * Load the configuration  
 */ 
private Properties load(URL url, String suffix) throws IOException {
	// figure out what we will be loading
	if (suffix != null && !suffix.equals("")) //$NON-NLS-1$
		url = new URL(url.getProtocol(),url.getHost(),url.getPort(),url.getFile()+suffix);
			
	// try to load saved configuration file
	Properties props = new Properties();
	InputStream is = null;
	try {
		is = url.openStream();
		props.load(is);
		// check to see if we have complete config file
		if (!CFG_EOF.equals(props.getProperty(CFG_EOF))) {
			throw new IOException();
		}
	} finally {
		if (is!=null) {
			try {
				is.close();
			} catch(IOException e) {
				//ignore failure to close
			}
		}
	}
	
	// load feature index
	if (props != null) {
		String id = props.getProperty(CFG_FEATURE_ENTRY+".0."+CFG_FEATURE_ENTRY_ID); //$NON-NLS-1$
		for (int i=1; id != null; i++) {
			featureIndex.put(id, Integer.toString(i-1));
			id = props.getProperty(CFG_FEATURE_ENTRY+"."+i+"."+CFG_FEATURE_ENTRY_ID); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}
	
	return props;
}	
	
/*
 * Load a configuration attribute
 */	
private String loadAttribute(Properties props, String name, String dflt) {
	if (props == null)
		return dflt;
		
	String prop = props.getProperty(name);
	if (prop == null)
		return dflt;
	else
		return prop.trim();
}

/*
 * Handle splash screen.
 * We support 2 startup scenarios:
 * 
 * (1) the executable launcher put up the splash screen. In that
 *     scenario we are invoked with -endsplash command which is
 *     fully formed to take down the splash screen
 * 
 * (2) the executable launcher did not put up the splash screen,
 *     but invokes Eclipse with partially formed -showsplash command.
 *     In this scenario we determine which splash to display (based on 
 *     feature information) and then call -showsplash command. 
 * 
 * In both scenarios we pass a handler (Runnable) to the platform.
 * The handler is called as a result of the launched application calling
 * Platform.endSplash(). In the first scenario this results in the
 * -endsplash command being executed. In the second scenarios this
 * results in the process created as a result of the -showsplash command
 * being destroyed.
 * 
 * @param bootPath search path for the boot plugin
 */
private void handleSplash(URL[] bootPath) {
	
	// run without splash if we are initializing
	if (cmdInitialize) {
		showSplash = null;
		endSplash = null;
		return;
	}
	
	// if -endsplash is specified, use it and ignore any -showsplash command
	if (endSplash != null) {
		showSplash = null;
		return;
	}
	
	// check if we are running without a splash screen
	if (showSplash == null)
		return;

	// determine the splash path
	String path  = getSplashPath(bootPath);
	if (debug && path != null) {
		System.out.println("Startup: splash path = "+path); //$NON-NLS-1$
	}
		
	// Parse the showsplash command into its separate arguments.
	// The command format is: 
	//     <executable> -show <magicArg> [<splashPath>]
	// If either the <executable> or the <splashPath> arguments contain a
	// space, Runtime.getRuntime().exec( String ) will not work, even
	// if both arguments are enclosed in double-quotes. The solution is to
	// use the Runtime.getRuntime().exec( String[] ) method.
	String[] cmd = new String[ (path != null ? 4 : 3) ];
	int sIndex = 0;
	int eIndex = showSplash.indexOf( " -show" ); //$NON-NLS-1$
	if (eIndex == -1)
		return; // invalid -showsplash command
	cmd[0] = showSplash.substring( sIndex, eIndex );
	sIndex = eIndex + 1;
	eIndex = showSplash.indexOf( " ", sIndex ); //$NON-NLS-1$
	if (eIndex == -1)
		return; // invalid -showsplash command
	cmd[1] = showSplash.substring( sIndex, eIndex );
	cmd[2] = showSplash.substring( eIndex+1 );
	if (path != null)
		cmd[3] = path;
	try {
		showProcess = Runtime.getRuntime().exec(cmd);
	} catch (Exception e) {
		// continue without splash ...
		log("Exception showing splash screen."); //$NON-NLS-1$
		log(e);
	}
	return;
}

/*
 * take down the splash screen. Try both take-down methods just in case
 * (only one should ever be set)
 */
private void takeDownSplash() {
	if (splashDown) // splash is already down
		return;
		
	// check if -endsplash was specified
	if (endSplash != null) {
		try {
			Runtime.getRuntime().exec(endSplash);
		} catch (Exception e) {
			//ignore failure to end splash
		}
	}
	
	// check if -showsplash was specified and executed
	if (showProcess != null) {
		showProcess.destroy();
		showProcess = null;
	}
	
	splashDown = true;
}

/*
 * Return path of the splash image to use
 */
private String getSplashPath(URL[] bootPath) {
	
	// see if we can get a splash for the launched feature
	String[] featurePath = getFeatureRoot();	
	String path = lookupSplash(featurePath);
	if (path != null)
		return path;
	
	// no feature path, default to current boot plugin
	String temp = bootPath[0].getFile(); // take the first path element
	temp = temp.replace('/', File.separatorChar);
	int ix = temp.lastIndexOf("plugins"+File.separator); //$NON-NLS-1$
	if (ix != -1) {
		int pix = temp.indexOf(File.separator, ix+8);
		if (pix != -1) {
			temp = temp.substring(0,pix);
			path = lookupSplash(new String[] { temp });
			return path;
		}
	}
		
	// sorry, no splash found
	return null;
}

/*
 * Do a locale-sensitive lookup of splash image
 */
 private String lookupSplash(String[] searchPath) {
 	if (searchPath == null)
 		return null;
 	
 	// get current locale information
 	String localePath = Locale.getDefault().toString().replace('_', File.separatorChar);
 	
 	// search the specified path
 	while (localePath != null) {
 		String suffix;
 		if (localePath.equals("")) { //$NON-NLS-1$
 			// look for nl'ed splash image
 			suffix = SPLASH_IMAGE;
 		} else {
 			// look for default splash image
 			suffix = "nl" + File.separator + localePath + File.separator + SPLASH_IMAGE; //$NON-NLS-1$
 		}
 			
 		// check for file in searchPath
 		for (int i=0; i<searchPath.length; i++) {
 			String path = searchPath[i];
 			if (!path.endsWith(File.separator))
 				path += File.separator;
 			path += suffix;
 			File splash = new File(path);
 			if (splash.exists())
 				return splash.getAbsolutePath(); // return the first match found [20063]
 		}
 		
 		// try the next variant
 		if (localePath.equals("")) //$NON-NLS-1$
 			localePath = null;
 		else {
 			int ix = localePath.lastIndexOf(File.separator);
 			if (ix == -1)
 				localePath = ""; //$NON-NLS-1$
 			else
 				localePath = localePath.substring(0,ix);
 		}
 	} 
 	
 	// sorry, could not find splash image
 	return null;
 }

/*
 * Return the feature identifier to use (specified or defaulted)
 */
private String getFeatureIdentifier() {
		
	if (feature != null) // -feature was specified on command line
		return feature; 
		
	// feature was not specified on command line
	String dflt = props.getProperty(CFG_FEATURE_ENTRY_DEFAULT);
	if (dflt != null)
		return dflt; // return customized default if set.
	else
		return null; // otherwise let BootLoader pick default
}

/*
 * Return the feature root if known
 */
private String[] getFeatureRoot() {
	String ix = featureIndex(getFeatureIdentifier());
	String urlString = props.getProperty(CFG_FEATURE_ENTRY + "." + ix + "." + CFG_FEATURE_ENTRY_ROOT + ".0"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	if (urlString == null)
		return null;
	
	ArrayList result = new ArrayList();
	URL url = null;
	for (int i=1; urlString != null; i++) {
		try {	
			urlString = resolve(urlString); // resolve platform relative URLs
			url = new URL(urlString);
			if (url.getProtocol().equals("file")) { //$NON-NLS-1$
				result.add(url.getFile().replace('/', File.separatorChar));
			} else
				continue; // in the future may cache
		} catch(MalformedURLException e) {
			// skip bad entries
		}
		urlString = props.getProperty(CFG_FEATURE_ENTRY + "." + ix + "." + CFG_FEATURE_ENTRY_ROOT + "." + i); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}
	
	if (result.size()>0)
		return (String[])result.toArray(new String[0]);
	else 
		return null;
}

/*
 * resolve platform:/base/ URLs
 */
 private String resolve(String urlString) throws MalformedURLException { 	
 	if (urlString.startsWith(PLATFORM_URL)) {
 		String root = getRootURL().toExternalForm();
 		if (!root.endsWith("/")) //$NON-NLS-1$
 			root += "/"; //$NON-NLS-1$
 		String path = urlString.substring(PLATFORM_URL.length());
 		return root + path;
 	} else
 		return urlString;
 }

/*
 * 
 */
private String featureIndex(String id) {
	if (id==null)
		return null;
	return (String)featureIndex.get(id);
}

/*
 * Entry point for logging.
 */
private static synchronized void log(Object obj) {
	if (obj == null)
		return;
	try {
		openLogFile();
		try {
			if (newSession) {
				log.write(SESSION);
				log.write(' ');
				for (int i=SESSION.length(); i<78; i++)
					log.write('-');
				log.newLine();
				newSession = false;
			}
			write(obj);
		} finally {
			if (logFile == null) {
				if (log != null)
					log.flush();
			} else
				closeLogFile();
		}
	} catch (Exception e) {
		System.err.println("An exception occurred while writing to the platform log:");//$NON-NLS-1$
		e.printStackTrace(System.err);
		System.err.println("Logging to the console instead.");//$NON-NLS-1$
		//we failed to write, so dump log entry to console instead
		try {
			log = logForStream(System.err);
			write(obj);
			log.flush();
		} catch (Exception e2) {
			System.err.println("An exception occurred while logging to the console:");//$NON-NLS-1$
			e2.printStackTrace(System.err);
		}
	} finally {
			log = null;
	}
}
/*
 * This should only be called from #log()
 */
private static void write(Object obj) throws IOException {
	if (obj == null)
		return;
	if (obj instanceof Throwable) {
		log.write(STACK);
		log.newLine();
		((Throwable) obj).printStackTrace(new PrintWriter(log));
	} else {
		log.write(ENTRY);
		log.write(' ');
		log.write(PLUGIN_ID);
		log.write(' ');
		log.write(String.valueOf(ERROR));
		log.write(' ');
		log.write(String.valueOf(0));
		log.write(' ');
		try {
			DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy kk:mm:ss.SS"); //$NON-NLS-1$
			log.write(formatter.format(new Date()));
		} catch (Exception e) {
			// continue if we can't write out the date
			log.write(Long.toString(System.currentTimeMillis()));
		}
		log.newLine();
		log.write(MESSAGE);
		log.write(' ');
		log.write(String.valueOf(obj));
	}
	log.newLine();
}
private static void computeLogFileLocation() {
	if (logFile != null)
		return;
	// compute the base location and then append the name of the log file
	File base = computeMetadataLocation();
	logFile = new File(base, ".log"); //$NON-NLS-1$
	logFile.getParentFile().mkdirs();
}
private static File computeLockFileLocation() {
	// compute the base location and then append the name of the lock file
	File base = computeMetadataLocation();
	File result = new File(base, ".lock"); //$NON-NLS-1$
	result.getParentFile().mkdirs();
	return result;
}
private static File computeMetadataLocation() {

	File result = null;
	// check to see if the user specified a workspace location in the command-line args
	for (int i=0; arguments != null && result == null && i<arguments.length; i++) {
		if (arguments[i].equalsIgnoreCase(DATA)) {
			// found the -data command line argument so the next argument should be the
			// workspace location. Ensure that we have another arg to check
			if (i+1<arguments.length)
				result = new File(arguments[i+1]);
		}
	}
	// otherwise use the default location
	if (result == null)
		result = new File(System.getProperty("user.dir"), "workspace");//$NON-NLS-1$ //$NON-NLS-2$
	
	// append the .metadata directory to the path
	return new File(result, ".metadata"); //$NON-NLS-1$
}
/**
 * Converts an ASCII character representing a hexadecimal
 * value into its integer equivalent.
 */
private int hexToByte(byte b) {
	switch (b) {
		case '0':return 0;
		case '1':return 1;
		case '2':return 2;
		case '3':return 3;
		case '4':return 4;
		case '5':return 5;
		case '6':return 6;
		case '7':return 7;
		case '8':return 8;
		case '9':return 9;
		case 'A':
		case 'a':return 10;
		case 'B':
		case 'b':return 11;
		case 'C':
		case 'c':return 12;
		case 'D':
		case 'd':return 13;
		case 'E':
		case 'e':return 14;
		case 'F':
		case 'f':return 15;
		default:
			throw new IllegalArgumentException("Switch error decoding URL");
	}
}


private static void openLogFile() throws IOException {
	computeLogFileLocation();
	try {
		log = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath(), true), "UTF-8"));//$NON-NLS-1$
	} catch (IOException e) {
		logFile = null;
		throw e;
	}
}
private static BufferedWriter logForStream(OutputStream output) {
	try {
		return new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));//$NON-NLS-1$
	} catch (UnsupportedEncodingException e) {
		return new BufferedWriter(new OutputStreamWriter(output));
	}
}
private static void closeLogFile() throws IOException {
	try {
		if (log != null) {
			log.flush();
			log.close();
		}
	} finally {
		log = null;
	}
}
/**
 * Return a boolean value indicating whether or not the version of the JVM is
 * deemed to be compatible with Eclipse.
 */
private static boolean isCompatible() {
	try {
		String vmVersionString = System.getProperty("java.version"); //$NON-NLS-1$
		Identifier minimum = new Identifier(1, 3, 0);
		Identifier version = new Identifier(vmVersionString);
		return version.isGreaterEqualTo(minimum);
	} catch (SecurityException e) {
		// If the security manager won't allow us to get the system property, continue for
		// now and let things fail later on their own if necessary.
		return true;
	} catch (NumberFormatException e) {
		// If the version string was in a format that we don't understand, continue and
		// let things fail later on their own if necessary.
		return true;
	}
}
/**
 * Return a boolean value indicating whether or not the platform is already
 * running in this workspace.
 */
private static boolean isAlreadyRunning() {
	// Calculate the location of the lock file
	File lockFile = computeLockFileLocation();

	// if the lock file already exists, try to delete,
	// assume failure means another eclipse has it open
	if (lockFile.exists())
		lockFile.delete();
	return lockFile.exists();
}

}
