/*******************************************************************************
 * 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$
	private static final String ECLIPSE = "eclipse"; //$NON-NLS-1$
	private static final String PRODUCT_SITE_MARKER = ".eclipseproduct"; //$NON-NLS-1$
	private static final String PRODUCT_SITE_ID = "id"; //$NON-NLS-1$
	private static final String PRODUCT_SITE_VERSION = "version"; //$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;
}

/**
 * Returns the url of the default location for configuration.
 *  1) We store the config state relative to the 'eclipse' directory if possible
 *  2) If this directory is read-only
 *     we store the state in <user.home>/.eclipse/<application-id>_<version> where <user.home> 
 *     is unique for each local user, and <application-id> is the one 
 *     defined in .eclipseproduct marker file. If .eclipseproduct does not
 *     exist, use "eclipse" as the application-id.
 */
private URL getDefaultStateLocation() throws IOException {
	
	URL installURL = getRootURL();
	File installDir = new File(installURL.getFile());
		
	if ("file".equals(installURL.getProtocol()) && installDir.canWrite()) { //$NON-NLS-1$
		if (debug)
			System.out.println("Using the installation directory."); //$NON-NLS-1$
		return installURL;
	} else {	
		if (debug)
			System.out.println("Using the user.home location."); //$NON-NLS-1$
		String appName = "." + ECLIPSE; //$NON-NLS-1$
		File eclipseProduct = new File(installDir, PRODUCT_SITE_MARKER );
		if (eclipseProduct.exists()) {
			Properties props = new Properties();
			props.load(new FileInputStream(eclipseProduct));
			String appId = props.getProperty(PRODUCT_SITE_ID);
			if (appId == null || appId.trim().length() == 0)
				appId = ECLIPSE;
			String appVersion = props.getProperty(PRODUCT_SITE_VERSION);
			if (appVersion == null || appVersion.trim().length() == 0)
				appVersion = ""; //$NON-NLS-1$
			appName += File.separator+ appId + "_" + appVersion; //$NON-NLS-1$
		}
				
		String userHome = System.getProperty("user.home"); //$NON-NLS-1$
		File configDir = new File(userHome, appName);
		configDir.mkdirs();
		return configDir.toURL();
	}
}		

/*
 * Load the configuration file. If not specified, default to default state location
 */
private void loadConfiguration(URL url) {
	if (url == null) {
		// configuration URL was not specified ..... search
		URL defaultStateURL = null;
		try {
			defaultStateURL = getDefaultStateLocation();
			URL cfigURL = new URL(defaultStateURL, CONFIG_FILE);
			// first look for configuration in base location (workspace or as specified)
			props = loadProperties(cfigURL);
			if (debug)
				System.out.println("Startup: using configuration " + cfigURL.toString()); //$NON-NLS-1$
			return; // we're done looking
		} catch (IOException e1) {
			// .continue
		}
			
		try {
			File cfg = null;
			// 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();
}

}
