/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Anton Leherbauer (Wind River Systems) - bug 301226
 *******************************************************************************/
package org.eclipse.equinox.launcher;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import java.security.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.equinox.internal.launcher.Constants;

/**
 * The launcher for Eclipse.
 * 
 * <b>Note:</b> This class should not be referenced programmatically by
 * other Java code. This class exists only for the purpose of launching Eclipse
 * from the command line. To launch Eclipse programmatically, use 
 * org.eclipse.core.runtime.adaptor.EclipseStarter. The fields and methods
 * on this class are not API.
 * 
 * @noextend This class is not intended to be subclassed by clients.
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
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 URL installLocation = null;

	/**
	 * The location of the configuration information for this instance
	 */
	protected URL configurationLocation = null;

	/**
	 * The location of the configuration information in the install root
	 */
	protected String parentConfigurationLocation = null;

	/**
	 * The id of the bundle that will contain the framework to run.  Defaults to org.eclipse.osgi.
	 */
	protected String framework = OSGI;

	/**
	 * The extra development time class path entries for the framework.
	 */
	protected String devClassPath = null;

	/*
	 * The extra development time class path entries for all bundles.
	 */
	private Properties devClassPathProps = null;

	/**
	 * Indicates whether this instance is running in development mode.
	 */
	protected boolean inDevelopmentMode = false;

	/**
	 * Indicates which OS was passed in with -os
	 */
	protected String os = null;
	protected String ws = null;
	protected String arch = null;

	//    private String name = null; // The name to brand the launcher
	//    private String launcher = null; // The full path to the launcher
	private String library = null;
	private String exitData = null;

	private String vm = null;
	private String[] vmargs = null;
	private String[] commands = null;
	String[] extensionPaths = null;

	JNIBridge bridge = null;

	// splash handling
	private boolean showSplash = false;
	private String splashLocation = null;
	private String endSplash = null;
	private boolean initialize = false;
	protected boolean splashDown = false;

	public final class SplashHandler extends Thread {
		public void run() {
			takeDownSplash();
		}

		public void updateSplash() {
			if (bridge != null && !splashDown) {
				bridge.updateSplash();
			}
		}
	}

	private final Thread splashHandler = new SplashHandler();

	//splash screen system properties
	public static final String SPLASH_HANDLE = "org.eclipse.equinox.launcher.splash.handle"; //$NON-NLS-1$
	public static final String SPLASH_LOCATION = "org.eclipse.equinox.launcher.splash.location"; //$NON-NLS-1$

	// command line args
	private static final String FRAMEWORK = "-framework"; //$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 VM = "-vm"; //$NON-NLS-1$
	private static final String VMARGS = "-vmargs"; //$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 CONFIGURATION = "-configuration"; //$NON-NLS-1$
	private static final String NOSPLASH = "-nosplash"; //$NON-NLS-1$
	private static final String SHOWSPLASH = "-showsplash"; //$NON-NLS-1$
	private static final String EXITDATA = "-exitdata"; //$NON-NLS-1$
	private static final String NAME = "-name"; //$NON-NLS-1$
	private static final String LAUNCHER = "-launcher"; //$NON-NLS-1$
	private static final String LIBRARY = "--launcher.library"; //$NON-NLS-1$
	private static final String NL = "-nl"; //$NON-NLS-1$
	private static final String ENDSPLASH = "-endsplash"; //$NON-NLS-1$
	private static final String SPLASH_IMAGE = "splash.bmp"; //$NON-NLS-1$
	private static final String CLEAN = "-clean"; //$NON-NLS-1$
	private static final String NOEXIT = "-noExit"; //$NON-NLS-1$
	private static final String OS = "-os"; //$NON-NLS-1$
	private static final String WS = "-ws"; //$NON-NLS-1$
	private static final String ARCH = "-arch"; //$NON-NLS-1$
	private static final String STARTUP = "-startup"; //$NON-NLS-1$

	private static final String OSGI = "org.eclipse.osgi"; //$NON-NLS-1$
	private static final String STARTER = "org.eclipse.core.runtime.adaptor.EclipseStarter"; //$NON-NLS-1$
	private static final String PLATFORM_URL = "platform:/base/"; //$NON-NLS-1$
	private static final String ECLIPSE_PROPERTIES = "eclipse.properties"; //$NON-NLS-1$
	private static final String FILE_SCHEME = "file:"; //$NON-NLS-1$    
	protected static final String REFERENCE_SCHEME = "reference:"; //$NON-NLS-1$
	protected static final String JAR_SCHEME = "jar:"; //$NON-NLS-1$

	// constants: configuration file location
	private static final String CONFIG_DIR = "configuration/"; //$NON-NLS-1$
	private static final String CONFIG_FILE = "config.ini"; //$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 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: System property keys and/or configuration file elements
	private static final String PROP_USER_HOME = "user.home"; //$NON-NLS-1$
	private static final String PROP_USER_DIR = "user.dir"; //$NON-NLS-1$
	private static final String PROP_INSTALL_AREA = "osgi.install.area"; //$NON-NLS-1$
	private static final String PROP_CONFIG_AREA = "osgi.configuration.area"; //$NON-NLS-1$
	private static final String PROP_CONFIG_AREA_DEFAULT = "osgi.configuration.area.default"; //$NON-NLS-1$
	private static final String PROP_BASE_CONFIG_AREA = "osgi.baseConfiguration.area"; //$NON-NLS-1$
	private static final String PROP_SHARED_CONFIG_AREA = "osgi.sharedConfiguration.area"; //$NON-NLS-1$
	private static final String PROP_CONFIG_CASCADED = "osgi.configuration.cascaded"; //$NON-NLS-1$
	protected static final String PROP_FRAMEWORK = "osgi.framework"; //$NON-NLS-1$
	private static final String PROP_SPLASHPATH = "osgi.splashPath"; //$NON-NLS-1$
	private static final String PROP_SPLASHLOCATION = "osgi.splashLocation"; //$NON-NLS-1$
	private static final String PROP_CLASSPATH = "osgi.frameworkClassPath"; //$NON-NLS-1$
	private static final String PROP_EXTENSIONS = "osgi.framework.extensions"; //$NON-NLS-1$
	private static final String PROP_FRAMEWORK_SYSPATH = "osgi.syspath"; //$NON-NLS-1$
	private static final String PROP_FRAMEWORK_SHAPE = "osgi.framework.shape"; //$NON-NLS-1$
	private static final String PROP_LOGFILE = "osgi.logfile"; //$NON-NLS-1$
	private static final String PROP_REQUIRED_JAVA_VERSION = "osgi.requiredJavaVersion"; //$NON-NLS-1$
	private static final String PROP_PARENT_CLASSLOADER = "osgi.parentClassloader"; //$NON-NLS-1$
	private static final String PROP_FRAMEWORK_PARENT_CLASSLOADER = "osgi.frameworkParentClassloader"; //$NON-NLS-1$
	private static final String PROP_NL = "osgi.nl"; //$NON-NLS-1$
	static final String PROP_NOSHUTDOWN = "osgi.noShutdown"; //$NON-NLS-1$
	private static final String PROP_DEBUG = "osgi.debug"; //$NON-NLS-1$	
	private static final String PROP_OS = "osgi.os"; //$NON-NLS-1$
	private static final String PROP_WS = "osgi.ws"; //$NON-NLS-1$
	private static final String PROP_ARCH = "osgi.arch"; //$NON-NLS-1$

	private static final String PROP_EXITCODE = "eclipse.exitcode"; //$NON-NLS-1$
	private static final String PROP_EXITDATA = "eclipse.exitdata"; //$NON-NLS-1$
	private static final String PROP_LAUNCHER = "eclipse.launcher"; //$NON-NLS-1$
	private static final String PROP_LAUNCHER_NAME = "eclipse.launcher.name"; //$NON-NLS-1$

	private static final String PROP_VM = "eclipse.vm"; //$NON-NLS-1$
	private static final String PROP_VMARGS = "eclipse.vmargs"; //$NON-NLS-1$
	private static final String PROP_COMMANDS = "eclipse.commands"; //$NON-NLS-1$
	private static final String PROP_ECLIPSESECURITY = "eclipse.security"; //$NON-NLS-1$

	// Suffix for location properties - see LocationManager.
	private static final String READ_ONLY_AREA_SUFFIX = ".readOnly"; //$NON-NLS-1$

	// Data mode constants for user, configuration and data locations.
	private static final String NONE = "@none"; //$NON-NLS-1$
	private static final String NO_DEFAULT = "@noDefault"; //$NON-NLS-1$
	private static final String USER_HOME = "@user.home"; //$NON-NLS-1$
	private static final String USER_DIR = "@user.dir"; //$NON-NLS-1$

	// types of parent classloaders the framework can have
	private static final String PARENT_CLASSLOADER_APP = "app"; //$NON-NLS-1$
	private static final String PARENT_CLASSLOADER_EXT = "ext"; //$NON-NLS-1$
	private static final String PARENT_CLASSLOADER_BOOT = "boot"; //$NON-NLS-1$
	private static final String PARENT_CLASSLOADER_CURRENT = "current"; //$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.equinox.launcher"; //$NON-NLS-1$
	protected File logFile = null;
	protected BufferedWriter log = null;
	protected boolean newSession = true;

	/**
	 * A structured form for a version identifier.
	 * 
	 * @see "http://java.sun.com/j2se/versioning_naming.html for information on valid version strings"
	 */
	static class Identifier {
		private static final String DELIM = ". _-"; //$NON-NLS-1$
		private int major, minor, service;

		Identifier(int major, int minor, int service) {
			super();
			this.major = major;
			this.minor = minor;
			this.service = service;
		}

		/**
		 * @throws NumberFormatException if cannot parse the major and minor version components
		 */
		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());

			try {
				// service
				if (tokenizer.hasMoreTokens())
					service = Integer.parseInt(tokenizer.nextToken());
			} catch (NumberFormatException nfe) {
				// ignore the service qualifier in that case and default to 0
				// this will allow us to tolerate other non-conventional version numbers 
			}
		}

		/**
		 * 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
		 */
		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;
		}
	}

	private String getWS() {
		if (ws != null)
			return ws;

		String osgiWs = System.getProperty(PROP_WS);
		if (osgiWs != null) {
			ws = osgiWs;
			return ws;
		}

		String osName = getOS();
		if (osName.equals(Constants.OS_WIN32))
			return Constants.WS_WIN32;
		if (osName.equals(Constants.OS_LINUX))
			return Constants.WS_GTK;
		if (osName.equals(Constants.OS_MACOSX))
			return Constants.WS_COCOA;
		if (osName.equals(Constants.OS_HPUX))
			return Constants.WS_MOTIF;
		if (osName.equals(Constants.OS_AIX))
			return Constants.WS_MOTIF;
		if (osName.equals(Constants.OS_SOLARIS))
			return Constants.WS_GTK;
		if (osName.equals(Constants.OS_QNX))
			return Constants.WS_PHOTON;
		return Constants.WS_UNKNOWN;
	}

	private String getAlternateWS(String defaultWS) {
		// We'll have already tried the default, so we only need to map
		// in one direction. (default -> alternate)
		if (Constants.WS_COCOA.equals(defaultWS))
			return Constants.WS_CARBON;
		if (Constants.WS_GTK.equals(defaultWS))
			return Constants.WS_MOTIF;
		if (Constants.WS_WIN32.equals(defaultWS))
			return Constants.WS_WPF;
		return Constants.WS_UNKNOWN;
	}

	private String getOS() {
		if (os != null)
			return os;
		String osgiOs = System.getProperty(PROP_OS);
		if (osgiOs != null) {
			os = osgiOs;
			return os;
		}
		String osName = System.getProperties().getProperty("os.name"); //$NON-NLS-1$
		if (osName.regionMatches(true, 0, Constants.OS_WIN32, 0, 3))
			return Constants.OS_WIN32;
		// EXCEPTION: All mappings of SunOS convert to Solaris
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_SUNOS))
			return Constants.OS_SOLARIS;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_LINUX))
			return Constants.OS_LINUX;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_QNX))
			return Constants.OS_QNX;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_AIX))
			return Constants.OS_AIX;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_HPUX))
			return Constants.OS_HPUX;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_OS400))
			return Constants.OS_OS400;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_OS390))
			return Constants.OS_OS390;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_ZOS))
			return Constants.OS_ZOS;
		// os.name on Mac OS can be either Mac OS or Mac OS X
		if (osName.regionMatches(true, 0, Constants.INTERNAL_OS_MACOSX, 0, Constants.INTERNAL_OS_MACOSX.length()))
			return Constants.OS_MACOSX;
		return Constants.OS_UNKNOWN;
	}

	private String getArch() {
		if (arch != null)
			return arch;
		String osgiArch = System.getProperty(PROP_ARCH);
		if (osgiArch != null) {
			arch = osgiArch;
			return arch;
		}
		String name = System.getProperties().getProperty("os.arch");//$NON-NLS-1$
		// Map i386 architecture to x86
		if (name.equalsIgnoreCase(Constants.INTERNAL_ARCH_I386))
			return Constants.ARCH_X86;
		// Map amd64 architecture to x86_64
		else if (name.equalsIgnoreCase(Constants.INTERNAL_AMD64))
			return Constants.ARCH_X86_64;

		return name;
	}

	private String getFragmentString(String fragmentOS, String fragmentWS, String fragmentArch) {
		StringBuffer buffer = new StringBuffer(PLUGIN_ID);
		buffer.append('.');
		buffer.append(fragmentWS);
		buffer.append('.');
		buffer.append(fragmentOS);
		if (!(fragmentOS.equals(Constants.OS_MACOSX) && !Constants.ARCH_X86_64.equals(fragmentArch))) {
			buffer.append('.');
			buffer.append(fragmentArch);
		}
		return buffer.toString();
	}

	/**
	 *  Sets up the JNI bridge to native calls
	 */
	private void setupJNI(URL[] defaultPath) {
		String libPath = null;

		if (library != null) {
			File lib = new File(library);
			if (lib.isDirectory()) {
				libPath = searchFor("eclipse", lib.getAbsolutePath()); //$NON-NLS-1$
			} else if (lib.exists()) {
				libPath = lib.getAbsolutePath();
			}
		}
		if (libPath == null) {
			//find our fragment name
			String fragmentOS = getOS();
			String fragmentWS = getWS();
			String fragmentArch = getArch();

			libPath = getLibraryPath(getFragmentString(fragmentOS, fragmentWS, fragmentArch), defaultPath);
			if (libPath == null && ws == null) {
				// no ws was specified and we didn't find the default fragment, try an alternate ws
				String alternateWS = getAlternateWS(fragmentWS);
				libPath = getLibraryPath(getFragmentString(fragmentOS, alternateWS, fragmentArch), defaultPath);
				if (libPath != null) {
					System.getProperties().put(PROP_WS, alternateWS);
				}
			}
		}
		library = libPath;
		if (library != null)
			bridge = new JNIBridge(library);
	}

	private String getLibraryPath(String fragmentName, URL[] defaultPath) {
		String libPath = null;
		String fragment = null;
		if (inDevelopmentMode && devClassPathProps != null) {
			String devPathList = devClassPathProps.getProperty(PLUGIN_ID);
			String[] locations = getArrayFromList(devPathList);
			if (locations.length > 0) {
				File location = new File(locations[0]);
				if (location.isAbsolute()) {
					String dir = location.getParent();
					fragment = searchFor(fragmentName, dir);
					if (fragment != null)
						libPath = getLibraryFromFragment(fragment);
				}
			}
		}
		if (libPath == null && bootLocation != null) {
			URL[] urls = defaultPath;
			if (urls != null && urls.length > 0) {
				//the last one is most interesting
				for (int i = urls.length - 1; i >= 0 && libPath == null; i--) {
					File entryFile = new File(urls[i].getFile());
					String dir = entryFile.getParent();
					if (inDevelopmentMode) {
						String devDir = dir + "/" + PLUGIN_ID + "/fragments"; //$NON-NLS-1$ //$NON-NLS-2$
						fragment = searchFor(fragmentName, devDir);
					}
					if (fragment == null)
						fragment = searchFor(fragmentName, dir);
					if (fragment != null)
						libPath = getLibraryFromFragment(fragment);
				}
			}
		}
		if (libPath == null) {
			URL install = getInstallLocation();
			String location = install.getFile();
			location += "/plugins/"; //$NON-NLS-1$
			fragment = searchFor(fragmentName, location);
			if (fragment != null)
				libPath = getLibraryFromFragment(fragment);
		}
		return libPath;
	}

	private String getLibraryFromFragment(String fragment) {
		if (fragment.startsWith(FILE_SCHEME))
			fragment = fragment.substring(5);

		File frag = new File(fragment);
		if (!frag.exists())
			return null;

		if (frag.isDirectory())
			return searchFor("eclipse", fragment); //$NON-NLS-1$;

		ZipFile fragmentJar = null;
		try {
			fragmentJar = new ZipFile(frag);
		} catch (IOException e) {
			log("Exception opening JAR file: " + fragment); //$NON-NLS-1$
			log(e);
			return null;
		}

		Enumeration entries = fragmentJar.entries();
		String entry = null;
		while (entries.hasMoreElements()) {
			ZipEntry zipEntry = (ZipEntry) entries.nextElement();
			if (zipEntry.getName().startsWith("eclipse_")) { //$NON-NLS-1$
				entry = zipEntry.getName();
				try {
					fragmentJar.close();
				} catch (IOException e) {
					//ignore
				}
				break;
			}
		}
		if (entry != null) {
			String lib = extractFromJAR(fragment, entry);
			if (!getOS().equals("win32")) { //$NON-NLS-1$
				try {
					Runtime.getRuntime().exec(new String[] {"chmod", "755", lib}).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$
				} catch (Throwable e) {
					//ignore
				}
			}
			return lib;
		}
		return null;
	}

	/**
	 * Executes the launch.
	 * 
	 * @param args command-line arguments
	 * @exception Exception thrown if a problem occurs during the launch
	 */
	protected void basicRun(String[] args) throws Exception {
		System.getProperties().put("eclipse.startTime", Long.toString(System.currentTimeMillis())); //$NON-NLS-1$
		commands = args;
		String[] passThruArgs = processCommandLine(args);

		if (!debug)
			// debug can be specified as system property as well
			debug = System.getProperty(PROP_DEBUG) != null;
		setupVMProperties();
		processConfiguration();

		// need to ensure that getInstallLocation is called at least once to initialize the value.
		// Do this AFTER processing the configuration to allow the configuration to set
		// the install location.  
		getInstallLocation();

		// locate boot plugin (may return -dev mode variations)
		URL[] bootPath = getBootPath(bootLocation);

		//Set up the JNI bridge.  We need to know the install location to find the shared library
		setupJNI(bootPath);

		//ensure minimum Java version, do this after JNI is set up so that we can write an error message 
		//with exitdata if we fail.
		if (!checkVersion(System.getProperty("java.version"), System.getProperty(PROP_REQUIRED_JAVA_VERSION))) //$NON-NLS-1$
			return;

		// verify configuration location is writable
		if (!checkConfigurationLocation(configurationLocation))
			return;

		setSecurityPolicy(bootPath);
		// 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);

		beforeFwkInvocation();
		invokeFramework(passThruArgs, bootPath);
	}

	protected void beforeFwkInvocation() {
		//Nothing to do.
	}

	protected void setSecurityPolicy(URL[] bootPath) {
		String eclipseSecurity = System.getProperty(PROP_ECLIPSESECURITY);
		if (eclipseSecurity != null) {
			// setup a policy that grants the launcher and path for the framework AllPermissions.
			// Do not set the security manager, this will be done by the framework itself.
			ProtectionDomain domain = Main.class.getProtectionDomain();
			CodeSource source = null;
			if (domain != null)
				source = Main.class.getProtectionDomain().getCodeSource();
			if (domain == null || source == null) {
				log("Can not automatically set the security manager. Please use a policy file."); //$NON-NLS-1$
				return;
			}
			// get the list of codesource URLs to grant AllPermission to
			URL[] rootURLs = new URL[bootPath.length + 1];
			rootURLs[0] = source.getLocation();
			System.arraycopy(bootPath, 0, rootURLs, 1, bootPath.length);
			// replace the security policy
			Policy eclipsePolicy = new EclipsePolicy(Policy.getPolicy(), rootURLs);
			Policy.setPolicy(eclipsePolicy);
		}
	}

	private void invokeFramework(String[] passThruArgs, URL[] bootPath) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, Error, Exception, InvocationTargetException {
		String type = System.getProperty(PROP_FRAMEWORK_PARENT_CLASSLOADER, System.getProperty(PROP_PARENT_CLASSLOADER, PARENT_CLASSLOADER_BOOT));
		ClassLoader parent = null;
		if (PARENT_CLASSLOADER_APP.equalsIgnoreCase(type))
			parent = ClassLoader.getSystemClassLoader();
		else if (PARENT_CLASSLOADER_EXT.equalsIgnoreCase(type)) {
			ClassLoader appCL = ClassLoader.getSystemClassLoader();
			if (appCL != null)
				parent = appCL.getParent();
		} else if (PARENT_CLASSLOADER_CURRENT.equalsIgnoreCase(type))
			parent = this.getClass().getClassLoader();
		URLClassLoader loader = new StartupClassLoader(bootPath, parent);
		Class clazz = loader.loadClass(STARTER);
		Method method = clazz.getDeclaredMethod("run", new Class[] {String[].class, Runnable.class}); //$NON-NLS-1$
		try {
			method.invoke(clazz, new Object[] {passThruArgs, splashHandler});
		} catch (InvocationTargetException e) {
			if (e.getTargetException() instanceof Error)
				throw (Error) e.getTargetException();
			else if (e.getTargetException() instanceof Exception)
				throw (Exception) e.getTargetException();
			else
				//could be a subclass of Throwable!
				throw e;
		}
	}

	/**
	 * Checks whether the given available version is greater or equal to the 
	 * given required version.
	 * <p>Will set PROP_EXITCODE/PROP_EXITDATA accordingly if check fails.</p>
	 *   
	 * @return a boolean indicating whether the checking passed 
	 */
	private boolean checkVersion(String availableVersion, String requiredVersion) {
		if (requiredVersion == null || availableVersion == null)
			return true;
		try {
			Identifier required = new Identifier(requiredVersion);
			Identifier available = new Identifier(availableVersion);
			boolean compatible = available.isGreaterEqualTo(required);
			if (!compatible) {
				// any non-zero value should do it - 14 used to be used for version incompatibility in Eclipse 2.1 
				System.getProperties().put(PROP_EXITCODE, "14"); //$NON-NLS-1$
				System.getProperties().put(PROP_EXITDATA, "<title>Incompatible JVM</title>Version " + availableVersion + " of the JVM is not suitable for this product. Version: " + requiredVersion + " or greater is required."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
			return compatible;
		} 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;
		}
	}

	/**
	 * Checks whether the given location can be created and is writable.
	 * If the system property "osgi.configuration.area.readOnly" is set
	 * the check always succeeds.
	 * <p>Will set PROP_EXITCODE/PROP_EXITDATA accordingly if check fails.</p>
	 * 
	 * @param locationUrl  configuration area URL, may be <code>null</code>
	 * @return a boolean indicating whether the checking passed 
	 */
	private boolean checkConfigurationLocation(URL locationUrl) {
		if (locationUrl == null || !"file".equals(locationUrl.getProtocol())) //$NON-NLS-1$
			return true;
		if (Boolean.valueOf(System.getProperty(PROP_CONFIG_AREA + READ_ONLY_AREA_SUFFIX)).booleanValue()) {
			// user wants readonly config area
			return true;
		}
		File configDir = new File(locationUrl.getFile()).getAbsoluteFile();
		if (!configDir.exists()) {
			configDir.mkdirs();
			if (!configDir.exists()) {
				System.getProperties().put(PROP_EXITCODE, "15"); //$NON-NLS-1$
				System.getProperties().put(PROP_EXITDATA, "<title>Invalid Configuration Location</title>The configuration area at '" + configDir + //$NON-NLS-1$
						"' could not be created.  Please choose a writable location using the '-configuration' command line option."); //$NON-NLS-1$
				return false;
			}
		}
		if (!canWrite(configDir)) {
			System.getProperties().put(PROP_EXITCODE, "15"); //$NON-NLS-1$
			System.getProperties().put(PROP_EXITDATA, "<title>Invalid Configuration Location</title>The configuration area at '" + configDir + //$NON-NLS-1$
					"' is not writable.  Please choose a writable location using the '-configuration' command line option."); //$NON-NLS-1$
			return false;
		}
		return true;
	}

	/**
	 * 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 == '%') {
				if (i + 2 >= encodedLength)
					throw new IllegalArgumentException("Malformed URL (\"" + urlString + "\"): % must be followed by 2 digits."); //$NON-NLS-1$//$NON-NLS-2$
				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
	 */
	protected 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[list.size()]);
	}

	/**
	 * 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
	 */
	private URL[] getDevPath(URL base) throws IOException {
		ArrayList result = new ArrayList(5);
		if (inDevelopmentMode)
			addDevEntries(base, result, OSGI);
		//The jars from the base always need to be added, even when running in dev mode (bug 46772)
		addBaseJars(base, result);
		return (URL[]) result.toArray(new URL[result.size()]);
	}

	URL constructURL(URL url, String name) {
		//Recognize the following URLs
		//url: file:foo/dir/
		//url: file:foo/file.jar

		String externalForm = url.toExternalForm();
		if (externalForm.endsWith(".jar")) { //$NON-NLS-1$
			try {
				return new URL(JAR_SCHEME + url + "!/" + name); //$NON-NLS-1$
			} catch (MalformedURLException e) {
				//Ignore
			}
		}

		try {
			return new URL(url, name);
		} catch (MalformedURLException e) {
			//Ignore
			return null;
		}
	}

	private void readFrameworkExtensions(URL base, ArrayList result) throws IOException {
		String[] extensions = getArrayFromList(System.getProperties().getProperty(PROP_EXTENSIONS));
		String parent = new File(base.getFile()).getParent().toString();
		ArrayList extensionResults = new ArrayList(extensions.length);
		for (int i = 0; i < extensions.length; i++) {
			//Search the extension relatively to the osgi plugin 
			String path = searchForBundle(extensions[i], parent);
			if (path == null) {
				log("Could not find extension: " + extensions[i]); //$NON-NLS-1$
				continue;
			}
			if (debug)
				System.out.println("Loading extension: " + extensions[i]); //$NON-NLS-1$

			URL extensionURL = null;
			if (installLocation.getProtocol().equals("file")) { //$NON-NLS-1$
				extensionResults.add(path);
				extensionURL = new File(path).toURL();
			} else
				extensionURL = new URL(installLocation.getProtocol(), installLocation.getHost(), installLocation.getPort(), path);

			//Load a property file of the extension, merge its content, and in case of dev mode add the bin entries
			Properties extensionProperties = null;
			try {
				extensionProperties = loadProperties(constructURL(extensionURL, ECLIPSE_PROPERTIES));
			} catch (IOException e) {
				if (debug)
					System.out.println("\t" + ECLIPSE_PROPERTIES + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			String extensionClassPath = null;
			if (extensionProperties != null)
				extensionClassPath = extensionProperties.getProperty(PROP_CLASSPATH);
			else
				// this is a "normal" RFC 101 framework extension bundle just put the base path on the classpath
				extensionProperties = new Properties();
			String[] entries = extensionClassPath == null || extensionClassPath.length() == 0 ? new String[] {""} : getArrayFromList(extensionClassPath); //$NON-NLS-1$
			String qualifiedPath;
			if (System.getProperty(PROP_CLASSPATH) == null)
				qualifiedPath = "."; //$NON-NLS-1$
			else
				qualifiedPath = ""; //$NON-NLS-1$
			for (int j = 0; j < entries.length; j++)
				qualifiedPath += ", " + FILE_SCHEME + path + entries[j]; //$NON-NLS-1$
			extensionProperties.put(PROP_CLASSPATH, qualifiedPath);
			mergeProperties(System.getProperties(), extensionProperties);
			if (inDevelopmentMode) {
				String name = extensions[i];
				if (name.startsWith(REFERENCE_SCHEME)) {
					// need to extract the BSN from the path
					name = new File(path).getName();
					// Note that we do not extract any version information.
					// We assume the extension is located in the workspace in a project
					// that has the same name as the BSN.
					// We could add more logic here to support versions in project folder names
					// but it will likely be complicated and error prone.
				}
				addDevEntries(extensionURL, result, name);
			}
		}
		extensionPaths = (String[]) extensionResults.toArray(new String[extensionResults.size()]);
	}

	private void addBaseJars(URL base, ArrayList result) throws IOException {
		String baseJarList = System.getProperty(PROP_CLASSPATH);
		if (baseJarList == null) {
			readFrameworkExtensions(base, result);
			baseJarList = System.getProperties().getProperty(PROP_CLASSPATH);
		}

		File fwkFile = new File(base.getFile());
		boolean fwkIsDirectory = fwkFile.isDirectory();
		//We found where the fwk is, remember it and its shape
		if (fwkIsDirectory) {
			System.getProperties().put(PROP_FRAMEWORK_SHAPE, "folder");//$NON-NLS-1$
		} else {
			System.getProperties().put(PROP_FRAMEWORK_SHAPE, "jar");//$NON-NLS-1$
		}
		String fwkPath = new File(new File(base.getFile()).getParent()).getAbsolutePath();
		if (Character.isUpperCase(fwkPath.charAt(0))) {
			char[] chars = fwkPath.toCharArray();
			chars[0] = Character.toLowerCase(chars[0]);
			fwkPath = new String(chars);
		}
		System.getProperties().put(PROP_FRAMEWORK_SYSPATH, fwkPath);

		String[] baseJars = getArrayFromList(baseJarList);
		if (baseJars.length == 0) {
			if (!inDevelopmentMode && new File(base.getFile()).isDirectory())
				throw new IOException("Unable to initialize " + PROP_CLASSPATH); //$NON-NLS-1$
			addEntry(base, result);
			return;
		}
		for (int i = 0; i < baseJars.length; i++) {
			String string = baseJars[i];
			try {
				// if the string is a file: URL then *carefully* construct the
				// URL. Otherwisejust try to build a URL. In either case, if we fail, use
				// string as something to tack on the end of the base.

				if (string.equals(".")) { //$NON-NLS-1$
					addEntry(base, result);
				}
				URL url = null;
				if (string.startsWith(FILE_SCHEME))
					url = new File(string.substring(5)).toURL();
				else
					url = new URL(string);
				addEntry(url, result);
			} catch (MalformedURLException e) {
				addEntry(new URL(base, string), result);
			}
		}
	}

	protected void addEntry(URL url, List result) {
		if (new File(url.getFile()).exists())
			result.add(url);
	}

	private void addDevEntries(URL base, List result, String symbolicName) throws MalformedURLException {
		if (devClassPathProps == null)
			return; // do nothing
		String devPathList = devClassPathProps.getProperty(symbolicName);
		if (devPathList == null)
			devPathList = devClassPathProps.getProperty("*"); //$NON-NLS-1$
		String[] locations = getArrayFromList(devPathList);
		for (int i = 0; i < locations.length; i++) {
			String location = locations[i];
			File path = new File(location);
			URL url;
			if (path.isAbsolute())
				url = path.toURL();
			else {
				// dev path is relative, combine with base location
				char lastChar = location.charAt(location.length() - 1);
				if ((location.endsWith(".jar") || (lastChar == '/' || lastChar == '\\'))) //$NON-NLS-1$
					url = new URL(base, location);
				else
					url = new URL(base, location + "/"); //$NON-NLS-1$
			}
			addEntry(url, result);
		}
	}

	/**
	 * 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 IOException {
		URL url = null;
		if (base != null) {
			url = buildURL(base, true);
		} else {
			// search in the root location
			url = getInstallLocation();
			String path = new File(url.getFile(), "plugins").toString(); //$NON-NLS-1$
			path = searchFor(framework, path);
			if (path == null)
				throw new RuntimeException("Could not find framework"); //$NON-NLS-1$
			if (url.getProtocol().equals("file")) //$NON-NLS-1$
				url = new File(path).toURL();
			else
				url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
		}
		if (System.getProperty(PROP_FRAMEWORK) == null)
			System.getProperties().put(PROP_FRAMEWORK, url.toExternalForm());
		if (debug)
			System.out.println("Framework located:\n    " + url.toExternalForm()); //$NON-NLS-1$
		// add on any dev path elements
		URL[] result = getDevPath(url);
		if (debug) {
			System.out.println("Framework classpath:"); //$NON-NLS-1$
			for (int i = 0; i < result.length; i++)
				System.out.println("    " + result[i].toExternalForm()); //$NON-NLS-1$
		}
		return result;
	}

	/**
	 * Searches for the given target 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 target directory was found
	 * @param start the location to begin searching
	 */
	protected String searchFor(final String target, String start) {
		return searchFor(target, null, start);
	}

	protected String searchFor(final String target, final String targetSuffix, String start) {
		File root = resolveFile(new File(start));

		// Note that File.list only gives you file names not the complete path from start
		String[] candidates = root.list();
		if (candidates == null)
			return null;

		ArrayList matches = new ArrayList(2);
		for (int i = 0; i < candidates.length; i++) {
			if (isMatchingCandidate(target, candidates[i], root))
				matches.add(candidates[i]);
		}
		String[] names = (String[]) matches.toArray(new String[matches.size()]);
		int result = findMax(target, names);
		if (result == -1)
			return null;
		File candidate = new File(start, names[result]);
		return candidate.getAbsolutePath().replace(File.separatorChar, '/') + (candidate.isDirectory() ? "/" : ""); //$NON-NLS-1$//$NON-NLS-2$
	}

	private boolean isMatchingCandidate(String target, String candidate, File root) {
		if (candidate.equals(target))
			return true;
		if (!candidate.startsWith(target + "_")) //$NON-NLS-1$
			return false;
		int targetLength = target.length();
		int lastUnderscore = candidate.lastIndexOf('_');

		//do we have a second '_', version (foo_1.0.0.v1_123) or id (foo.x86_64) ?
		//files are assumed to have an extension (zip or jar only), remove it
		//NOTE: we only remove .zip and .jar extensions because we still need to accept libraries with
		//simple versions (e.g. eclipse_1234.dll)
		File candidateFile = new File(root, candidate);
		if (candidateFile.isFile() && (candidate.endsWith(".jar") || candidate.endsWith(".zip"))) { //$NON-NLS-1$//$NON-NLS-2$
			int extension = candidate.lastIndexOf('.');
			candidate = candidate.substring(0, extension);
		}

		int lastDot = candidate.lastIndexOf('.');
		if (lastDot < targetLength) {
			// no dots after target, the '_' is not in a version (foo.x86_64 case), not a match
			return false;
		}

		//get past all '_' that are part of the qualifier
		while (lastUnderscore > lastDot)
			lastUnderscore = candidate.lastIndexOf('_', lastUnderscore - 1);

		if (lastUnderscore == targetLength)
			return true; //underscore at the end of target (foo_1.0.0.v1_123 case)
		return false; //another underscore between target and version (foo_64_1.0.0.v1_123 case)
	}

	private String searchForBundle(String target, String start) {
		//Only handle "reference:file:" urls, and not simple "file:" because we will be using the jar wherever it is.
		if (target.startsWith(REFERENCE_SCHEME)) {
			target = target.substring(REFERENCE_SCHEME.length());
			if (!target.startsWith(FILE_SCHEME))
				throw new IllegalArgumentException("Bundle URL is invalid: " + target); //$NON-NLS-1$
			target = target.substring(FILE_SCHEME.length());
			File child = new File(target);
			File fileLocation = child;
			if (!child.isAbsolute()) {
				File parent = resolveFile(new File(start));
				fileLocation = new File(parent, child.getPath());
			}
			return searchFor(fileLocation.getName(), fileLocation.getParentFile().getAbsolutePath());
		}
		return searchFor(target, start);
	}

	protected int findMax(String prefix, String[] candidates) {
		int result = -1;
		Object maxVersion = null;
		for (int i = 0; i < candidates.length; i++) {
			String name = (candidates[i] != null) ? candidates[i] : ""; //$NON-NLS-1$
			String version = ""; //$NON-NLS-1$ // Note: directory with version suffix is always > than directory without version suffix
			if (prefix == null)
				version = name; //webstart just passes in versions
			else if (name.startsWith(prefix + "_")) //$NON-NLS-1$
				version = name.substring(prefix.length() + 1); //prefix_version
			Object currentVersion = getVersionElements(version);
			if (maxVersion == null) {
				result = i;
				maxVersion = currentVersion;
			} else {
				if (compareVersion((Object[]) maxVersion, (Object[]) currentVersion) < 0) {
					result = i;
					maxVersion = currentVersion;
				}
			}
		}
		return result;
	}

	/**
	 * 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) {
		if (version.endsWith(".jar")) //$NON-NLS-1$
			version = version.substring(0, version.length() - 4);
		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;
	}

	private static URL buildURL(String spec, boolean trailingSlash) {
		if (spec == null)
			return null;
		boolean isFile = spec.startsWith(FILE_SCHEME);
		try {
			if (isFile) {
				File toAdjust = new File(spec.substring(5));
				toAdjust = resolveFile(toAdjust);
				if (toAdjust.isDirectory())
					return adjustTrailingSlash(toAdjust.toURL(), trailingSlash);
				return toAdjust.toURL();
			}
			return new URL(spec);
		} catch (MalformedURLException e) {
			// if we failed and it is a file spec, there is nothing more we can do
			// otherwise, try to make the spec into a file URL.
			if (isFile)
				return null;
			try {
				File toAdjust = new File(spec);
				if (toAdjust.isDirectory())
					return adjustTrailingSlash(toAdjust.toURL(), trailingSlash);
				return toAdjust.toURL();
			} catch (MalformedURLException e1) {
				return null;
			}
		}
	}

	/**
	 * Resolve the given file against  osgi.install.area.
	 * If osgi.install.area is not set, or the file is not relative, then
	 * the file is returned as is. 
	 */
	private static File resolveFile(File toAdjust) {
		if (!toAdjust.isAbsolute()) {
			String installArea = System.getProperties().getProperty(PROP_INSTALL_AREA);
			if (installArea != null) {
				if (installArea.startsWith(FILE_SCHEME))
					toAdjust = new File(installArea.substring(5), toAdjust.getPath());
				else if (new File(installArea).exists())
					toAdjust = new File(installArea, toAdjust.getPath());
			}
		}
		return toAdjust;
	}

	private static URL adjustTrailingSlash(URL url, boolean trailingSlash) throws MalformedURLException {
		String file = url.getFile();
		if (trailingSlash == (file.endsWith("/"))) //$NON-NLS-1$
			return url;
		file = trailingSlash ? file + "/" : file.substring(0, file.length() - 1); //$NON-NLS-1$
		return new URL(url.getProtocol(), url.getHost(), file);
	}

	private URL buildLocation(String property, URL defaultLocation, String userDefaultAppendage) {
		URL result = null;
		String location = System.getProperty(property);
		System.getProperties().remove(property);
		// if the instance location is not set, predict where the workspace will be and 
		// put the instance area inside the workspace meta area.
		try {
			if (location == null)
				result = defaultLocation;
			else if (location.equalsIgnoreCase(NONE))
				return null;
			else if (location.equalsIgnoreCase(NO_DEFAULT))
				result = buildURL(location, true);
			else {
				if (location.startsWith(USER_HOME)) {
					String base = substituteVar(location, USER_HOME, PROP_USER_HOME);
					location = new File(base, userDefaultAppendage).getAbsolutePath();
				} else if (location.startsWith(USER_DIR)) {
					String base = substituteVar(location, USER_DIR, PROP_USER_DIR);
					location = new File(base, userDefaultAppendage).getAbsolutePath();
				}
				result = buildURL(location, true);
			}
		} finally {
			if (result != null)
				System.getProperties().put(property, result.toExternalForm());
		}
		return result;
	}

	private String substituteVar(String source, String var, String prop) {
		String value = System.getProperty(prop, ""); //$NON-NLS-1$
		return value + source.substring(var.length());
	}

	/** 
	 * Retuns the default file system path for the configuration location.
	 * By default the configuration information is in the installation directory
	 * if this is writeable.  Otherwise it is located somewhere in the user.home
	 * area relative to the current product. 
	 * @return the default file system path for the configuration information
	 */
	private String computeDefaultConfigurationLocation() {
		// 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.

		URL install = getInstallLocation();
		// TODO a little dangerous here.  Basically we have to assume that it is a file URL.
		if (install.getProtocol().equals("file")) { //$NON-NLS-1$
			File installDir = new File(install.getFile());
			if (canWrite(installDir))
				return installDir.getAbsolutePath() + File.separator + CONFIG_DIR;
		}
		// We can't write in the eclipse install dir so try for some place in the user's home dir
		return computeDefaultUserAreaLocation(CONFIG_DIR);
	}

	private static boolean canWrite(File installDir) {
		if (installDir.canWrite() == false)
			return false;

		if (!installDir.isDirectory())
			return false;

		File fileTest = null;
		try {
			// we use the .dll suffix to properly test on Vista virtual directories
			// on Vista you are not allowed to write executable files on virtual directories like "Program Files"
			fileTest = File.createTempFile("writtableArea", ".dll", installDir); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (IOException e) {
			//If an exception occured while trying to create the file, it means that it is not writtable
			return false;
		} finally {
			if (fileTest != null)
				fileTest.delete();
		}
		return true;
	}

	/**
	 * Returns a files system path for an area in the user.home region related to the
	 * current product.  The given appendage is added to this base location
	 * @param pathAppendage the path segments to add to computed base
	 * @return a file system location in the user.home area related the the current
	 *   product and the given appendage
	 */
	private String computeDefaultUserAreaLocation(String pathAppendage) {
		//    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.
		URL installURL = getInstallLocation();
		if (installURL == null)
			return null;
		File installDir = new File(installURL.getFile());
		// compute an install dir hash to prevent configuration area collisions with other eclipse installs
		int hashCode;
		try {
			hashCode = installDir.getCanonicalPath().hashCode();
		} catch (IOException ioe) {
			// fall back to absolute path
			hashCode = installDir.getAbsolutePath().hashCode();
		}
		if (hashCode < 0)
			hashCode = -(hashCode);
		String installDirHash = String.valueOf(hashCode);

		String appName = "." + ECLIPSE; //$NON-NLS-1$
		File eclipseProduct = new File(installDir, PRODUCT_SITE_MARKER);
		if (eclipseProduct.exists()) {
			Properties props = new Properties();
			try {
				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 + "_" + installDirHash; //$NON-NLS-1$ //$NON-NLS-2$
			} catch (IOException e) {
				// Do nothing if we get an exception.  We will default to a standard location 
				// in the user's home dir.
				// add the hash to help prevent collisions
				appName += File.separator + installDirHash;
			}
		} else {
			// add the hash to help prevent collisions
			appName += File.separator + installDirHash;
		}
		String userHome = System.getProperty(PROP_USER_HOME);
		return new File(userHome, appName + "/" + pathAppendage).getAbsolutePath(); //$NON-NLS-1$
	}

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

	/**
	 * 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>.
	 * </p>
	 * 
	 * @param args the command line arguments
	 * @see #run(String[])
	 */
	public static void main(String[] args) {
		int result = 0;
		try {
			result = new Main().run(args);
		} catch (Throwable t) {
			// This is *really* unlikely to happen - run() takes care of exceptional situations.
			// In case something weird happens, just dump stack - logging is not available at this point
			t.printStackTrace();
		} finally {
			if (!Boolean.getBoolean(PROP_NOSHUTDOWN))
				// make sure we always terminate the VM
				System.exit(result);
		}
	}

	/**
	 * Runs the platform with the given arguments.  The arguments must identify
	 * an application to run (e.g., <code>-application com.example.application</code>).
	 * Returns 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.
	 *
	 * @param args the command line arguments
	 */
	public int run(String[] args) {
		int result = 0;
		try {
			basicRun(args);
			String exitCode = System.getProperty(PROP_EXITCODE);
			try {
				result = exitCode == null ? 0 : Integer.parseInt(exitCode);
			} catch (NumberFormatException e) {
				result = 17;
			}
		} catch (Throwable e) {
			// only log the exceptions if they have not been caught by the 
			// EclipseStarter (i.e., if the exitCode is not 13) 
			if (!"13".equals(System.getProperty(PROP_EXITCODE))) { //$NON-NLS-1$
				log("Exception launching the Eclipse Platform:"); //$NON-NLS-1$
				log(e);
				String message = "An error has occurred"; //$NON-NLS-1$
				if (logFile == null)
					message += " and could not be logged: \n" + e.getMessage(); //$NON-NLS-1$
				else
					message += ".  See the log file\n" + logFile.getAbsolutePath(); //$NON-NLS-1$
				System.getProperties().put(PROP_EXITDATA, message);
			}
			// 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.
			result = 13;
		} finally {
			// always try putting down the splash screen just in case the application failed to do so
			takeDownSplash();
			if (bridge != null)
				bridge.uninitialize();
		}
		// Return an int exit code and ensure the system property is set.
		System.getProperties().put(PROP_EXITCODE, Integer.toString(result));
		setExitData();
		return result;
	}

	private void setExitData() {
		String data = System.getProperty(PROP_EXITDATA);
		if (data == null)
			return;
		//if the bridge is null then we have nothing to send the data to;
		//exitData is a shared memory id, if we loaded the library from java, we need a non-null exitData
		//if the executable loaded the library, then we don't need the exitData id
		if (bridge == null || (bridge.isLibraryLoadedByJava() && exitData == null))
			System.out.println(data);
		else
			bridge.setExitData(exitData, data);
	}

	/**
	 * Processes the command line arguments.  The general principle is to NOT
	 * consume the arguments and leave them to be processed by Eclipse proper.
	 * There are a few args which are directed towards main() and a few others
	 * which we need to know about. Very few should actually be consumed here.
	 * 
	 * @return the arguments to pass through to the launched application
	 * @param args the command line arguments
	 */
	protected String[] processCommandLine(String[] args) {
		if (args.length == 0)
			return args;
		int[] configArgs = new int[args.length];
		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;
			}

			// look for and consume the nosplash directive.  This supercedes any
			// -showsplash command that might be present.
			if (args[i].equalsIgnoreCase(NOSPLASH)) {
				splashDown = true;
				found = true;
			}

			if (args[i].equalsIgnoreCase(NOEXIT)) {
				System.getProperties().put(PROP_NOSHUTDOWN, "true"); //$NON-NLS-1$
				found = true;
			}

			// check if this is initialization pass
			if (args[i].equalsIgnoreCase(INITIALIZE)) {
				initialize = 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;
			}

			// look for the command to use to show the splash screen
			if (args[i].equalsIgnoreCase(SHOWSPLASH)) {
				showSplash = true;
				found = true;
				//consume optional parameter for showsplash
				if (i + 1 < args.length && !args[i + 1].startsWith("-")) { //$NON-NLS-1$
					configArgs[configArgIndex++] = i++;
					splashLocation = args[i];
				}
			}

			// done checking for args.  Remember where an arg was found 
			if (found) {
				configArgs[configArgIndex++] = i;
				continue;
			}

			// look for the VM args arg.  We have to do that before looking to see
			// if the next element is a -arg as the thing following -vmargs may in
			// fact be another -arg.
			if (args[i].equalsIgnoreCase(VMARGS)) {
				// consume the -vmargs arg itself
				args[i] = null;
				i++;
				vmargs = new String[args.length - i];
				for (int j = 0; i < args.length; i++) {
					vmargs[j++] = args[i];
					args[i] = null;
				}
				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 development mode and class path entries.  
			if (args[i - 1].equalsIgnoreCase(DEV)) {
				inDevelopmentMode = true;
				devClassPathProps = processDevArg(arg);
				if (devClassPathProps != null) {
					devClassPath = devClassPathProps.getProperty(OSGI);
					if (devClassPath == null)
						devClassPath = devClassPathProps.getProperty("*"); //$NON-NLS-1$
				}
				continue;
			}

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

			if (args[i - 1].equalsIgnoreCase(OS)) {
				os = arg;
				// passed thru this arg 
				continue;
			}

			if (args[i - 1].equalsIgnoreCase(WS)) {
				ws = arg;
				continue;
			}

			if (args[i - 1].equalsIgnoreCase(ARCH)) {
				arch = arg;
				continue;
			}

			// look for explicitly set install root
			// Consume the arg here to ensure that the launcher and Eclipse get the 
			// same value as each other.  
			if (args[i - 1].equalsIgnoreCase(INSTALL)) {
				System.getProperties().put(PROP_INSTALL_AREA, arg);
				found = true;
			}

			// look for the configuration to use.  
			// Consume the arg here to ensure that the launcher and Eclipse get the 
			// same value as each other.  
			if (args[i - 1].equalsIgnoreCase(CONFIGURATION)) {
				System.getProperties().put(PROP_CONFIG_AREA, arg);
				found = true;
			}

			if (args[i - 1].equalsIgnoreCase(EXITDATA)) {
				exitData = arg;
				found = true;
			}

			// look for the name to use by the launcher
			if (args[i - 1].equalsIgnoreCase(NAME)) {
				System.getProperties().put(PROP_LAUNCHER_NAME, arg);
				found = true;
			}

			// look for the startup jar used 
			if (args[i - 1].equalsIgnoreCase(STARTUP)) {
				//not doing anything with this right now, but still consume it
				//startup = arg;
				found = true;
			}

			// look for the launcher location
			if (args[i - 1].equalsIgnoreCase(LAUNCHER)) {
				//not doing anything with this right now, but still consume it
				//launcher = arg;
				System.getProperties().put(PROP_LAUNCHER, arg);
				found = true;
			}

			if (args[i - 1].equalsIgnoreCase(LIBRARY)) {
				library = arg;
				found = true;
			}

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

			// look for the VM location arg
			if (args[i - 1].equalsIgnoreCase(VM)) {
				vm = arg;
				found = true;
			}

			//look for the nl setting
			if (args[i - 1].equalsIgnoreCase(NL)) {
				System.getProperties().put(PROP_NL, 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
		String[] passThruArgs = new String[args.length - configArgIndex - (vmargs == null ? 0 : vmargs.length + 1)];
		configArgIndex = 0;
		int j = 0;
		for (int i = 0; i < args.length; i++) {
			if (i == configArgs[configArgIndex])
				configArgIndex++;
			else if (args[i] != null)
				passThruArgs[j++] = args[i];
		}
		return passThruArgs;
	}

	private Properties processDevArg(String arg) {
		if (arg == null)
			return null;
		try {
			URL location = new URL(arg);
			return load(location, null);
		} catch (MalformedURLException e) {
			// the arg was not a URL so use it as is.
			Properties result = new Properties();
			result.put("*", arg); //$NON-NLS-1$
			return result;
		} catch (IOException e) {
			// TODO consider logging here
			return null;
		}
	}

	private URL getConfigurationLocation() {
		if (configurationLocation != null)
			return configurationLocation;
		configurationLocation = buildLocation(PROP_CONFIG_AREA, null, ""); //$NON-NLS-1$
		if (configurationLocation == null) {
			configurationLocation = buildLocation(PROP_CONFIG_AREA_DEFAULT, null, ""); //$NON-NLS-1$
			if (configurationLocation == null)
				configurationLocation = buildURL(computeDefaultConfigurationLocation(), true);
		}
		if (configurationLocation != null)
			System.getProperties().put(PROP_CONFIG_AREA, configurationLocation.toExternalForm());
		if (debug)
			System.out.println("Configuration location:\n    " + configurationLocation); //$NON-NLS-1$
		return configurationLocation;
	}

	private void processConfiguration() {
		// if the configuration area is not already defined, discover the config area by
		// trying to find a base config area.  This is either defined in a system property or
		// is computed relative to the install location.
		// Note that the config info read here is only used to determine a value 
		// for the user configuration area
		URL baseConfigurationLocation = null;
		Properties baseConfiguration = null;
		if (System.getProperty(PROP_CONFIG_AREA) == null) {
			String baseLocation = System.getProperty(PROP_BASE_CONFIG_AREA);
			if (baseLocation != null)
				// here the base config cannot have any symbolic (e..g, @xxx) entries.  It must just
				// point to the config file.
				baseConfigurationLocation = buildURL(baseLocation, true);
			if (baseConfigurationLocation == null)
				try {
					// here we access the install location but this is very early.  This case will only happen if
					// the config area is not set and the base config area is not set (or is bogus).
					// In this case we compute based on the install location.
					baseConfigurationLocation = new URL(getInstallLocation(), CONFIG_DIR);
				} catch (MalformedURLException e) {
					// leave baseConfigurationLocation null
				}
			baseConfiguration = loadConfiguration(baseConfigurationLocation);
			if (baseConfiguration != null) {
				// if the base sets the install area then use that value if the property.  We know the 
				// property is not already set.
				String location = baseConfiguration.getProperty(PROP_CONFIG_AREA);
				if (location != null)
					System.getProperties().put(PROP_CONFIG_AREA, location);
				// if the base sets the install area then use that value if the property is not already set.
				// This helps in selfhosting cases where you cannot easily compute the install location
				// from the code base.
				location = baseConfiguration.getProperty(PROP_INSTALL_AREA);
				if (location != null && System.getProperty(PROP_INSTALL_AREA) == null)
					System.getProperties().put(PROP_INSTALL_AREA, location);
			}
		}

		// Now we know where the base configuration is supposed to be.  Go ahead and load
		// it and merge into the System properties.  Then, if cascaded, read the parent configuration
		// Note that the parent may or may not be the same parent as we read above since the 
		// base can define its parent.  The first parent we read was either defined by the user
		// on the command line or was the one in the install dir.  
		// if the config or parent we are about to read is the same as the base config we read above,
		// just reuse the base
		Properties configuration = baseConfiguration;
		if (configuration == null || !getConfigurationLocation().equals(baseConfigurationLocation))
			configuration = loadConfiguration(getConfigurationLocation());
		mergeProperties(System.getProperties(), configuration);
		if ("false".equalsIgnoreCase(System.getProperty(PROP_CONFIG_CASCADED))) //$NON-NLS-1$
			// if we are not cascaded then remove the parent property even if it was set.
			System.getProperties().remove(PROP_SHARED_CONFIG_AREA);
		else {
			ensureAbsolute(PROP_SHARED_CONFIG_AREA);
			URL sharedConfigURL = buildLocation(PROP_SHARED_CONFIG_AREA, null, ""); //$NON-NLS-1$
			if (sharedConfigURL == null)
				try {
					// there is no shared config value so compute one
					sharedConfigURL = new URL(getInstallLocation(), CONFIG_DIR);
				} catch (MalformedURLException e) {
					// leave sharedConfigurationLocation null
				}
			// if the parent location is different from the config location, read it too.
			if (sharedConfigURL != null) {
				if (sharedConfigURL.equals(getConfigurationLocation()))
					// remove the property to show that we do not have a parent.
					System.getProperties().remove(PROP_SHARED_CONFIG_AREA);
				else {
					// if the parent we are about to read is the same as the base config we read above,
					// just reuse the base
					configuration = baseConfiguration;
					if (!sharedConfigURL.equals(baseConfigurationLocation))
						configuration = loadConfiguration(sharedConfigURL);
					mergeProperties(System.getProperties(), configuration);
					System.getProperties().put(PROP_SHARED_CONFIG_AREA, sharedConfigURL.toExternalForm());
					if (debug)
						System.out.println("Shared configuration location:\n    " + sharedConfigURL.toExternalForm()); //$NON-NLS-1$
				}
			}
		}
		// setup the path to the framework
		String urlString = System.getProperty(PROP_FRAMEWORK, null);
		if (urlString != null) {
			urlString = resolve(urlString);
			//ensure that the install location is set before resolving framework
			getInstallLocation();
			URL url = buildURL(urlString, true);
			urlString = url.toExternalForm();
			System.getProperties().put(PROP_FRAMEWORK, urlString);
			bootLocation = urlString;
		}
	}

	/**
	 * Ensures the value for a system property is an absolute URL. Relative URLs are translated to
	 * absolute URLs by taking the install URL as reference.
	 *   
	 * @param locationProperty the key for a system property containing a URL
	 */
	private void ensureAbsolute(String locationProperty) {
		String propertyValue = System.getProperty(locationProperty);
		if (propertyValue == null)
			// property not defined
			return;
		URL locationURL = null;
		try {
			locationURL = new URL(propertyValue);
		} catch (MalformedURLException e) {
			// property is not a valid URL
			return;
		}
		String locationPath = locationURL.getPath();
		if (locationPath.startsWith("/")) //$NON-NLS-1$
			// property value is absolute
			return;
		URL installURL = getInstallLocation();
		if (!locationURL.getProtocol().equals(installURL.getProtocol()))
			// not same protocol
			return;
		try {
			URL absoluteURL = new URL(installURL, locationPath);
			System.getProperties().put(locationProperty, absoluteURL.toExternalForm());
		} catch (MalformedURLException e) {
			// should not happen - the relative URL is known to be valid
		}
	}

	/**
	 * Returns url of the location this class was loaded from
	 */
	private URL getInstallLocation() {
		if (installLocation != null)
			return installLocation;

		// value is not set so compute the default and set the value
		String installArea = System.getProperty(PROP_INSTALL_AREA);
		if (installArea != null) {
			installLocation = buildURL(installArea, true);
			if (installLocation == null)
				throw new IllegalStateException("Install location is invalid: " + installArea); //$NON-NLS-1$
			System.getProperties().put(PROP_INSTALL_AREA, installLocation.toExternalForm());
			if (debug)
				System.out.println("Install location:\n    " + installLocation); //$NON-NLS-1$
			return installLocation;
		}

		ProtectionDomain domain = Main.class.getProtectionDomain();
		CodeSource source = null;
		URL result = null;
		if (domain != null)
			source = domain.getCodeSource();
		if (source == null || domain == null) {
			if (debug)
				System.out.println("CodeSource location is null. Defaulting the install location to file:startup.jar"); //$NON-NLS-1$
			try {
				result = new URL("file:startup.jar"); //$NON-NLS-1$
			} catch (MalformedURLException e2) {
				//Ignore
			}
		}
		if (source != null)
			result = source.getLocation();

		String path = decode(result.getFile());
		// normalize to not have leading / so we can check the form
		File file = new File(path);
		path = file.toString().replace('\\', '/');
		// TODO need a better test for windows
		// If on Windows then canonicalize the drive letter to be lowercase.
		// remember that there may be UNC paths 
		if (File.separatorChar == '\\')
			if (Character.isUpperCase(path.charAt(0))) {
				char[] chars = path.toCharArray();
				chars[0] = Character.toLowerCase(chars[0]);
				path = new String(chars);
			}
		if (path.toLowerCase().endsWith(".jar")) //$NON-NLS-1$
			path = path.substring(0, path.lastIndexOf("/") + 1); //$NON-NLS-1$
		if (path.toLowerCase().endsWith("/plugins/")) //$NON-NLS-1$ 
			path = path.substring(0, path.length() - "/plugins/".length()); //$NON-NLS-1$
		try {
			try {
				// create a file URL (via File) to normalize the form (e.g., put 
				// the leading / on if necessary)
				path = new File(path).toURL().getFile();
			} catch (MalformedURLException e1) {
				// will never happen.  The path is straight from a URL.  
			}
			installLocation = new URL(result.getProtocol(), result.getHost(), result.getPort(), path);
			System.getProperties().put(PROP_INSTALL_AREA, installLocation.toExternalForm());
		} catch (MalformedURLException e) {
			// TODO Very unlikely case.  log here.  
		}
		if (debug)
			System.out.println("Install location:\n    " + installLocation); //$NON-NLS-1$
		return installLocation;
	}

	/*
	 * Load the given configuration file
	 */
	private Properties loadConfiguration(URL url) {
		Properties result = null;
		try {
			url = new URL(url, CONFIG_FILE);
		} catch (MalformedURLException e) {
			return null;
		}
		try {
			if (debug)
				System.out.print("Configuration file:\n    " + url.toString()); //$NON-NLS-1$
			result = loadProperties(url);
			if (debug)
				System.out.println(" loaded"); //$NON-NLS-1$
		} catch (IOException e) {
			if (debug)
				System.out.println(" not found or not read"); //$NON-NLS-1$
		}
		return result;
	}

	private Properties loadProperties(URL url) throws IOException {
		// try to load saved configuration file (watch for failed prior save())
		if (url == null)
			return null;
		Properties result = null;
		IOException originalException = null;
		try {
			result = load(url, null); // try to load config file
		} catch (IOException e1) {
			originalException = e1;
			try {
				result = load(url, CONFIG_FILE_TEMP_SUFFIX); // check for failures on save
			} catch (IOException e2) {
				try {
					result = load(url, CONFIG_FILE_BAK_SUFFIX); // check for failures on save
				} catch (IOException e3) {
					throw originalException; // we tried, but no config here ...
				}
			}
		}
		return result;
	}

	/*
	 * 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);
		} finally {
			if (is != null)
				try {
					is.close();
				} catch (IOException e) {
					//ignore failure to close
				}
		}
		return props;
	}

	/*
	 * Handle splash screen.
	 *  The splash screen is displayed natively.  Whether or not the splash screen
	 *  was displayed by the launcher, we invoke JNIBridge.showSplash() and the 
	 *  native code handles the case of the splash screen already existing.
	 * 
	 * The -showsplash argument may indicate the bitmap used by the native launcher,
	 * or the bitmap location may be extracted from the config.ini
	 * 
	 * We pass a handler (Runnable) to the platform which is called as a result of the
	 * launched application calling Platform.endSplash(). This handle calls 
	 * JNIBridge.takeDownSplash and the native code will close the splash screen.
	 * 
	 * The -endsplash argument is longer used and has the same result as -nosplash
	 * 
	 * @param defaultPath search path for the boot plugin
	 */
	private void handleSplash(URL[] defaultPath) {
		// run without splash if we are initializing or nosplash 
		// was specified (splashdown = true)
		if (initialize || splashDown || bridge == null) {
			showSplash = false;
			endSplash = null;
			return;
		}

		if (showSplash || endSplash != null) {
			// Register the endSplashHandler to be run at VM shutdown. This hook will be 
			// removed once the splash screen has been taken down.
			try {
				Runtime.getRuntime().addShutdownHook(splashHandler);
			} catch (Throwable ex) {
				// Best effort to register the handler
			}
		}

		// if -endsplash is specified, use it and ignore any -showsplash command
		if (endSplash != null) {
			showSplash = false;
			return;
		}

		// check if we are running without a splash screen
		if (!showSplash)
			return;

		// determine the splash location
		splashLocation = getSplashLocation(defaultPath);
		if (debug)
			System.out.println("Splash location:\n    " + splashLocation); //$NON-NLS-1$
		if (splashLocation == null)
			return;

		bridge.setLauncherInfo(System.getProperty(PROP_LAUNCHER), System.getProperty(PROP_LAUNCHER_NAME));
		bridge.showSplash(splashLocation);
		long handle = bridge.getSplashHandle();
		if (handle != 0 && handle != -1) {
			System.getProperties().put(SPLASH_HANDLE, String.valueOf(handle));
			System.getProperties().put(SPLASH_LOCATION, splashLocation);
			bridge.updateSplash();
		} else {
			// couldn't show the splash screen for some reason
			splashDown = true;
		}
	}

	/*
	 * Take down the splash screen. 
	 */
	protected void takeDownSplash() {
		if (splashDown || bridge == null) // splash is already down
			return;

		splashDown = bridge.takeDownSplash();
		System.getProperties().remove(SPLASH_HANDLE);

		try {
			Runtime.getRuntime().removeShutdownHook(splashHandler);
		} catch (Throwable e) {
			// OK to ignore this, happens when the VM is already shutting down
		}
	}

	/*
	 * Return path of the splash image to use.  First search the defined splash path.
	 * If that does not work, look for a default splash.  Currently the splash must be in the file system
	 * so the return value here is the file system path.
	 */
	private String getSplashLocation(URL[] bootPath) {
		//check the path passed in from -showsplash first.  The old launcher passed a timeout value
		//as the argument, so only use it if it isn't a number and the file exists.
		if (splashLocation != null && !Character.isDigit(splashLocation.charAt(0)) && new File(splashLocation).exists()) {
			System.getProperties().put(PROP_SPLASHLOCATION, splashLocation);
			return splashLocation;
		}
		String result = System.getProperty(PROP_SPLASHLOCATION);
		if (result != null)
			return result;
		String splashPath = System.getProperty(PROP_SPLASHPATH);
		if (splashPath != null) {
			String[] entries = getArrayFromList(splashPath);
			ArrayList path = new ArrayList(entries.length);
			for (int i = 0; i < entries.length; i++) {
				String entry = resolve(entries[i]);
				if (entry != null && entry.startsWith(FILE_SCHEME)) {
					File entryFile = new File(entry.substring(5).replace('/', File.separatorChar));
					entry = searchFor(entryFile.getName(), entryFile.getParent());
					if (entry != null)
						path.add(entry);
				} else
					log("Invalid splash path entry: " + entries[i]); //$NON-NLS-1$
			}
			// see if we can get a splash given the splash path
			result = searchForSplash((String[]) path.toArray(new String[path.size()]));
			if (result != null) {
				System.getProperties().put(PROP_SPLASHLOCATION, result);
				return result;
			}
		}
		return result;
	}

	/*
	 * Do a locale-sensitive lookup of splash image
	 */
	private String searchForSplash(String[] searchPath) {
		if (searchPath == null)
			return null;

		// Get the splash screen for the specified locale
		String locale = (String) System.getProperties().get(PROP_NL);
		if (locale == null)
			locale = Locale.getDefault().toString();
		String[] nlVariants = buildNLVariants(locale);

		for (int i = 0; i < nlVariants.length; i++) {
			for (int j = 0; j < searchPath.length; j++) {
				String path = searchPath[j];
				if (path.startsWith(FILE_SCHEME))
					path = path.substring(5);
				// do we have a JAR?
				if (isJAR(path)) {
					String result = extractFromJAR(path, nlVariants[i]);
					if (result != null)
						return result;
				} else {
					// we have a file or a directory
					if (!path.endsWith(File.separator))
						path += File.separator;
					path += nlVariants[i];
					File result = new File(path);
					if (result.exists())
						return result.getAbsolutePath(); // return the first match found [20063]
				}
			}
		}

		// sorry, could not find splash image
		return null;
	}

	/**
	 * Transfers all available bytes from the given input stream to the given output stream. 
	 * Regardless of failure, this method closes both streams.
	 */
	private static void transferStreams(InputStream source, OutputStream destination) {
		byte[] buffer = new byte[8096];
		try {
			while (true) {
				int bytesRead = -1;
				try {
					bytesRead = source.read(buffer);
				} catch (IOException e) {
					return;
				}
				if (bytesRead == -1)
					break;
				try {
					destination.write(buffer, 0, bytesRead);
				} catch (IOException e) {
					return;
				}
			}
		} finally {
			try {
				source.close();
			} catch (IOException e) {
				// ignore
			} finally {
				//close destination in finally in case source.close fails
				try {
					destination.close();
				} catch (IOException e) {
					// ignore
				}
			}
		}
	}

	/*
	 * Look for the specified spash file in the given JAR and extract it to the config 
	 * area for caching purposes.
	 */
	private String extractFromJAR(String jarPath, String jarEntry) {
		String configLocation = System.getProperty(PROP_CONFIG_AREA);
		if (configLocation == null) {
			log("Configuration area not set yet. Unable to extract " + jarEntry + " from JAR'd plug-in: " + jarPath); //$NON-NLS-1$ //$NON-NLS-2$
			return null;
		}
		URL configURL = buildURL(configLocation, false);
		if (configURL == null)
			return null;
		// cache the splash in the equinox launcher sub-dir in the config area
		File splash = new File(configURL.getPath(), PLUGIN_ID);
		//include the name of the jar in the cache location
		File jarFile = new File(jarPath);
		String cache = jarFile.getName();
		if (cache.endsWith(".jar")) //$NON-NLS-1$
			cache = cache.substring(0, cache.length() - 4);
		splash = new File(splash, cache);
		splash = new File(splash, jarEntry);
		// if we have already extracted this file before, then return
		if (splash.exists()) {
			// if we are running with -clean then delete the cached splash file
			boolean clean = false;
			for (int i = 0; i < commands.length; i++) {
				if (CLEAN.equalsIgnoreCase(commands[i])) {
					clean = true;
					splash.delete();
					break;
				}
			}
			if (!clean)
				return splash.getAbsolutePath();
		}
		ZipFile file;
		try {
			file = new ZipFile(jarPath);
		} catch (IOException e) {
			log("Exception looking for " + jarEntry + " in JAR file: " + jarPath); //$NON-NLS-1$ //$NON-NLS-2$
			log(e);
			return null;
		}
		ZipEntry entry = file.getEntry(jarEntry.replace(File.separatorChar, '/'));
		if (entry == null)
			return null;
		InputStream input = null;
		try {
			input = file.getInputStream(entry);
		} catch (IOException e) {
			log("Exception opening splash: " + entry.getName() + " in JAR file: " + jarPath); //$NON-NLS-1$ //$NON-NLS-2$
			log(e);
			return null;
		}
		new File(splash.getParent()).mkdirs();
		OutputStream output;
		try {
			output = new BufferedOutputStream(new FileOutputStream(splash));
		} catch (FileNotFoundException e) {
			try {
				input.close();
			} catch (IOException e1) {
				// ignore
			}
			return null;
		}
		transferStreams(input, output);
		return splash.exists() ? splash.getAbsolutePath() : null;
	}

	/*
	 * Return a boolean value indicating whether or not the given
	 * path represents a JAR file.
	 */
	private boolean isJAR(String path) {
		return new File(path).isFile();
	}

	/*
	 * Build an array of path suffixes based on the given NL which is suitable
	 * for splash path searching.  The returned array contains paths in order 
	 * from most specific to most generic. So, in the FR_fr locale, it will return 
	 * "nl/fr/FR/splash.bmp", then "nl/fr/splash.bmp", and finally "splash.bmp". 
	 * (we always search the root)
	 */
	private static String[] buildNLVariants(String locale) {
		//build list of suffixes for loading resource bundles
		String nl = locale;
		ArrayList result = new ArrayList(4);
		int lastSeparator;
		while (true) {
			result.add("nl" + File.separatorChar + nl.replace('_', File.separatorChar) + File.separatorChar + SPLASH_IMAGE); //$NON-NLS-1$
			lastSeparator = nl.lastIndexOf('_');
			if (lastSeparator == -1)
				break;
			nl = nl.substring(0, lastSeparator);
		}
		//add the empty suffix last (most general)
		result.add(SPLASH_IMAGE);
		return (String[]) result.toArray(new String[result.size()]);
	}

	/*
	 * resolve platform:/base/ URLs
	 */
	private String resolve(String urlString) {
		// handle the case where people mistakenly spec a refererence: url.
		if (urlString.startsWith(REFERENCE_SCHEME))
			urlString = urlString.substring(10);
		if (urlString.startsWith(PLATFORM_URL)) {
			String path = urlString.substring(PLATFORM_URL.length());
			return getInstallLocation() + path;
		}
		return urlString;
	}

	/*
	 * Entry point for logging.
	 */
	protected synchronized void log(Object obj) {
		if (obj == null)
			return;
		try {
			openLogFile();
			try {
				if (newSession) {
					log.write(SESSION);
					log.write(' ');
					String timestamp = new Date().toString();
					log.write(timestamp);
					log.write(' ');
					for (int i = SESSION.length() + timestamp.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 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(' ');
			log.write(getDate(new Date()));
			log.newLine();
			log.write(MESSAGE);
			log.write(' ');
			log.write(String.valueOf(obj));
		}
		log.newLine();
	}

	protected String getDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		StringBuffer sb = new StringBuffer();
		appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-');
		appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-');
		appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' ');
		appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':');
		appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':');
		appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.');
		appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb);
		return sb.toString();
	}

	private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) {
		pad = pad - 1;
		if (pad == 0)
			return buffer.append(Integer.toString(value));
		int padding = (int) Math.pow(10, pad);
		if (value >= padding)
			return buffer.append(Integer.toString(value));
		while (padding > value && padding > 1) {
			buffer.append('0');
			padding = padding / 10;
		}
		buffer.append(value);
		return buffer;
	}

	private void computeLogFileLocation() {
		String logFileProp = System.getProperty(PROP_LOGFILE);
		if (logFileProp != null) {
			if (logFile == null || !logFileProp.equals(logFile.getAbsolutePath())) {
				logFile = new File(logFileProp);
				new File(logFile.getParent()).mkdirs();
			}
			return;
		}

		// compute the base location and then append the name of the log file
		URL base = buildURL(System.getProperty(PROP_CONFIG_AREA), false);
		if (base == null)
			return;
		logFile = new File(base.getPath(), Long.toString(System.currentTimeMillis()) + ".log"); //$NON-NLS-1$
		new File(logFile.getParent()).mkdirs();
		System.getProperties().put(PROP_LOGFILE, logFile.getAbsolutePath());
	}

	/**
	 * 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"); //$NON-NLS-1$
		}
	}

	private 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 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 void closeLogFile() throws IOException {
		try {
			if (log != null) {
				log.flush();
				log.close();
			}
		} finally {
			log = null;
		}
	}

	private void mergeProperties(Properties destination, Properties source) {
		if (destination == null || source == null)
			return;
		for (Enumeration e = source.keys(); e.hasMoreElements();) {
			String key = (String) e.nextElement();
			if (key.equals(PROP_CLASSPATH)) {
				String destinationClasspath = destination.getProperty(PROP_CLASSPATH);
				String sourceClasspath = source.getProperty(PROP_CLASSPATH);
				if (destinationClasspath == null)
					destinationClasspath = sourceClasspath;
				else
					destinationClasspath = destinationClasspath + sourceClasspath;
				destination.put(PROP_CLASSPATH, destinationClasspath);
				continue;
			}
			String value = source.getProperty(key);
			if (destination.getProperty(key) == null)
				destination.put(key, value);
		}
	}

	private void setupVMProperties() {
		if (vm != null)
			System.getProperties().put(PROP_VM, vm);
		setMultiValueProperty(PROP_VMARGS, vmargs);
		setMultiValueProperty(PROP_COMMANDS, commands);
	}

	private void setMultiValueProperty(String property, String[] value) {
		if (value != null) {
			StringBuffer result = new StringBuffer(300);
			for (int i = 0; i < value.length; i++) {
				if (value[i] != null) {
					result.append(value[i]);
					result.append('\n');
				}
			}
			System.getProperties().put(property, result.toString());
		}
	}

	/*
	 * NOTE: It is ok here for EclipsePolicy to use 1.4 methods because the methods
	 * that it calls them from don't exist in Foundation so they will never be called. A more
	 * detailed explanation from Tom:
	 * 
	 * They will never get called because in a pre 1.4 VM the methods 
	 * getPermissions(CodeSource) and implies(ProtectionDomain, Permission) are 
	 * undefined on the Policy class which is what EclipsePolicy extends.  EclipsePolicy 
	 * implements these two methods so it can proxy them to the parent Policy.  
	 * But since these methods are not actually defined on Policy in a pre-1.4 VM 
	 * nobody will actually call them (unless they casted the policy to EclipsePolicy and 
	 * called our methods)
	 */
	private class EclipsePolicy extends Policy {
		// The policy that this EclipsePolicy is replacing
		private Policy policy;

		// The set of URLs to give AllPermissions to; this is the set of bootURLs
		private URL[] urls;

		// The AllPermissions collection
		private PermissionCollection allPermissions;

		// The AllPermission permission
		Permission allPermission = new AllPermission();

		EclipsePolicy(Policy policy, URL[] urls) {
			this.policy = policy;
			this.urls = urls;
			allPermissions = new PermissionCollection() {
				private static final long serialVersionUID = 3258131349494708277L;

				// A simple PermissionCollection that only has AllPermission
				public void add(Permission permission) {
					//no adding to this policy
				}

				public boolean implies(Permission permission) {
					return true;
				}

				public Enumeration elements() {
					return new Enumeration() {
						int cur = 0;

						public boolean hasMoreElements() {
							return cur < 1;
						}

						public Object nextElement() {
							if (cur == 0) {
								cur = 1;
								return allPermission;
							}
							throw new NoSuchElementException();
						}
					};
				}
			};
		}

		public PermissionCollection getPermissions(CodeSource codesource) {
			if (contains(codesource))
				return allPermissions;
			return policy == null ? allPermissions : policy.getPermissions(codesource);
		}

		public PermissionCollection getPermissions(ProtectionDomain domain) {
			if (contains(domain.getCodeSource()))
				return allPermissions;
			return policy == null ? allPermissions : policy.getPermissions(domain);
		}

		public boolean implies(ProtectionDomain domain, Permission permission) {
			if (contains(domain.getCodeSource()))
				return true;
			return policy == null ? true : policy.implies(domain, permission);
		}

		public void refresh() {
			if (policy != null)
				policy.refresh();
		}

		private boolean contains(CodeSource codeSource) {
			if (codeSource == null)
				return false;
			URL url = codeSource.getLocation();
			if (url == null)
				return false;
			// Check to see if this URL is in our set of URLs to give AllPermissions to.
			for (int i = 0; i < urls.length; i++) {
				// We do simple equals test here because we assume the URLs will be the same objects.
				if (urls[i] == url)
					return true;
			}
			return false;
		}
	}

	private class StartupClassLoader extends URLClassLoader {

		public StartupClassLoader(URL[] urls) {
			super(urls);
		}

		public StartupClassLoader(URL[] urls, ClassLoader parent) {
			super(urls, parent);
		}

		public StartupClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
			super(urls, parent, factory);
		}

		protected String findLibrary(String name) {
			if (extensionPaths == null)
				return super.findLibrary(name);
			String libName = System.mapLibraryName(name);
			for (int i = 0; i < extensionPaths.length; i++) {
				File libFile = new File(extensionPaths[i], libName);
				if (libFile.isFile())
					return libFile.getAbsolutePath();
			}
			return super.findLibrary(name);
		}
	}
}
