/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Red Hat Inc. - bug 373640, 379102
 *     Ericsson AB (Pascal Rapicault) - bug 304132
 *     Rapicorp, Inc - Default the configuration to Application Support (bug 461725)
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 221969
 *******************************************************************************/
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 PROTECT = "-protect"; //$NON-NLS-1$
	//currently the only level of protection we care about.
	private static final String PROTECT_MASTER = "master"; //$NON-NLS-1$
	private static final String PROTECT_BASE = "base"; //$NON-NLS-1$

	private static final String LIBRARY = "--launcher.library"; //$NON-NLS-1$
	private static final String APPEND_VMARGS = "--launcher.appendVmargs"; //$NON-NLS-1$
	private static final String OVERRIDE_VMARGS = "--launcher.overrideVmargs"; //$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$
	// Placeholder for hashcode of installation directory
	private static final String INSTALL_HASH_PLACEHOLDER = "@install.hash"; //$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;

	private boolean protectBase = false;

	// for variable substitution
	public static final String VARIABLE_DELIM_STRING = "$"; //$NON-NLS-1$
	public static final char VARIABLE_DELIM_CHAR = '$';

	//for change detection in the base when running in shared install mode
	private static final long NO_TIMESTAMP = -1;
	private static final String BASE_TIMESTAMP_FILE_CONFIGINI = ".baseConfigIniTimestamp"; //$NON-NLS-1$
	private static final String KEY_CONFIGINI_TIMESTAMP = "configIniTimestamp"; //$NON-NLS-1$
	private static final String PROP_IGNORE_USER_CONFIGURATION = "eclipse.ignoreUserConfiguration"; //$NON-NLS-1$

	/**
	 * A structured form for a version identifier.
	 * 
	 * @see "http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html for information on valid version strings"
	 * @see "http://openjdk.java.net/jeps/223 for information on the JavaSE-9 version JEP 223"
	 */
	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());

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

				// service
				if (tokenizer.hasMoreTokens())
					service = Integer.parseInt(tokenizer.nextToken());
			} catch (NumberFormatException nfe) {
				// ignore the minor and service qualifiers 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) {
		if (bridge != null)
			return;

		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<? extends ZipEntry> entries = fragmentJar.entries();
		String entry = null;
		while (entries.hasMoreElements()) {
			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();

		if (protectBase && (System.getProperty(PROP_SHARED_CONFIG_AREA) == null)) {
			System.err.println("This application is configured to run in a cascaded mode only."); //$NON-NLS-1$
			System.setProperty(PROP_EXITCODE, "" + 14); //$NON-NLS-1$
			return;
		}
		// 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 = PARENT_CLASSLOADER_BOOT;
		try {
			String javaVersion = System.getProperty("java.version"); //$NON-NLS-1$
			if (javaVersion != null && new Identifier(javaVersion).isGreaterEqualTo(new Identifier("1.9"))) { //$NON-NLS-1$
				// Workaround for bug 466683. Some org.w3c.dom.* packages that used to be available from
				// JavaSE's boot classpath are only available from the extension path in Java 9 b62.
				// Workaround for bug 489958. javax.annotation.* types are only available from
				// JavaSE-9's extension path in Java 9-ea+108. The identifier "1.9" could be changed to "9", but "1.9" works just as well.
				type = PARENT_CLASSLOADER_EXT;
			}
		} 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.
		} 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.
		}
		type = System.getProperty(PROP_PARENT_CLASSLOADER, type);
		type = System.getProperty(PROP_FRAMEWORK_PARENT_CLASSLOADER, type);
		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", String[].class, Runnable.class); //$NON-NLS-1$
		try {
			method.invoke(clazz, 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<URLDecoder> clazz = URLDecoder.class;
			Method method = clazz.getDeclaredMethod("decode", 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, 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<String> list = new Vector<String>();
		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] : 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<URL> result = new ArrayList<URL>(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 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<URL> result) throws IOException {
		String[] extensions = getArrayFromList(System.getProperties().getProperty(PROP_EXTENSIONS));
		String parent = new File(base.getFile()).getParent().toString();
		ArrayList<String> extensionResults = new ArrayList<String>(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, null);
			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 = extensionResults.toArray(new String[extensionResults.size()]);
	}

	private void addBaseJars(URL base, ArrayList<URL> 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<URL> result) {
		if (new File(url.getFile()).exists())
			result.add(url);
	}

	private void addDevEntries(URL base, List<URL> 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<String> matches = new ArrayList<String>(2);
		for (int i = 0; i < candidates.length; i++) {
			if (isMatchingCandidate(target, candidates[i], root))
				matches.add(candidates[i]);
		}
		String[] names = 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;
		if (File.separatorChar == '\\')
			spec = spec.trim();
		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();
				}
				int idx = location.indexOf(INSTALL_HASH_PLACEHOLDER);
				if (idx == 0) {
					throw new RuntimeException("The location cannot start with '" + INSTALL_HASH_PLACEHOLDER + "': " + location); //$NON-NLS-1$ //$NON-NLS-2$
				} else if (idx > 0) {
					location = location.substring(0, idx) + getInstallDirHash() + location.substring(idx + INSTALL_HASH_PLACEHOLDER.length());
				}
				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();
		if (protectBase) {
			return computeDefaultUserAreaLocation(CONFIG_DIR);
		}

		// 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());
		String installDirHash = getInstallDirHash();

		if (protectBase && Constants.OS_MACOSX.equals(os)) {
			initializeBridgeEarly();
			String macConfiguration = computeConfigurationLocationForMacOS();
			if (macConfiguration != null) {
				return macConfiguration;
			}
			if (debug)
				System.out.println("Computation of Mac specific configuration folder failed."); //$NON-NLS-1$
		}

		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;
		}
		appName += '_' + OS_WS_ARCHToString();
		String userHome = System.getProperty(PROP_USER_HOME);
		return new File(userHome, appName + "/" + pathAppendage).getAbsolutePath(); //$NON-NLS-1$
	}

	private String computeConfigurationLocationForMacOS() {
		if (bridge != null) {
			String folder = bridge.getOSRecommendedFolder();
			if (debug)
				System.out.println("App folder provided by MacOS is: " + folder); //$NON-NLS-1$
			if (folder != null)
				return folder + '/' + CONFIG_DIR;
		}
		return null;
	}

	private String OS_WS_ARCHToString() {
		return getOS() + '_' + getWS() + '_' + getArch();
	}

	private void initializeBridgeEarly() {
		setupJNI(null);
	}

	/**
	 * Return hash code identifying an absolute installation path
	 * @return hash code as String
	 */
	private String getInstallDirHash() {
		// compute an install dir hash to prevent configuration area collisions with other eclipse installs
		URL installURL = getInstallLocation();
		if (installURL == null)
			return ""; //$NON-NLS-1$
		File installDir = new File(installURL.getFile());
		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);
		return installDirHash;
	}

	/**
	 * Runs this launcher with the arguments specified in the given string.
	 * 
	 * @param argString the arguments string
	 */
	public static void main(String argString) {
		Vector<String> list = new Vector<String>(5);
		for (StringTokenizer tokens = new StringTokenizer(argString, " "); tokens.hasMoreElements();) //$NON-NLS-1$
			list.addElement(tokens.nextToken());
		main(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 the return code is 23, that means that Equinox requested a restart.
			// In order to distinguish the request for a restart, do a System.exit(23)
			// no matter of 'osgi.noShutdown' runtime property value.
			if (!Boolean.getBoolean(PROP_NOSHUTDOWN) || result == 23)
				// 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);
			} else {
				// we have an exit code of 13, in most cases the user tries to start a 32/64 bit Eclipse
				// on a 64/32 bit Eclipse
				log("Are you trying to start an 64/32-bit Eclipse on a 32/64-JVM? These must be the same, as Eclipse uses native code.");
			}
			// 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;
			}

			//just consume the --launcher.overrideVmargs and --launcher.appendVmargs
			if (args[i].equalsIgnoreCase(APPEND_VMARGS) || args[i].equalsIgnoreCase(OVERRIDE_VMARGS)) {
				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];
				}
			}

			// look for the command to use to show the splash screen
			if (args[i].equalsIgnoreCase(PROTECT)) {
				found = true;
				//consume next parameter
				configArgs[configArgIndex++] = i++;
				if (args[i].equalsIgnoreCase(PROTECT_MASTER) || args[i].equalsIgnoreCase(PROTECT_BASE)) {
					protectBase = true;
				}
			}

			// 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) {
			ensureAbsolute(PROP_BASE_CONFIG_AREA);
			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 in a cascaded situation, the user configuration may be ignored if the parent 
		// configuration has changed since the user configuration has been written. 
		// 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());

		if (configuration != null && "false".equalsIgnoreCase(configuration.getProperty(PROP_CONFIG_CASCADED))) { //$NON-NLS-1$
			System.getProperties().remove(PROP_SHARED_CONFIG_AREA);
			configuration.remove(PROP_SHARED_CONFIG_AREA);
			mergeProperties(System.getProperties(), configuration, null);
		} 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())) {
					//After all we are not in a shared configuration setup.
					// - remove the property to show that we do not have a parent 
					// - merge configuration with the system properties 
					System.getProperties().remove(PROP_SHARED_CONFIG_AREA);
					mergeProperties(System.getProperties(), configuration, null);
				} else {
					// if the parent we are about to read is the same as the base config we read above,
					// just reuse the base
					Properties sharedConfiguration = baseConfiguration;
					if (!sharedConfigURL.equals(baseConfigurationLocation)) {
						sharedConfiguration = loadConfiguration(sharedConfigURL);
					}
					long sharedConfigTimestamp = getCurrentConfigIniBaseTimestamp(sharedConfigURL);
					long lastKnownBaseTimestamp = getLastKnownConfigIniBaseTimestamp();
					if (debug)
						System.out.println("Timestamps found: \n\t config.ini in the base: " + sharedConfigTimestamp + "\n\t remembered " + lastKnownBaseTimestamp); //$NON-NLS-1$ //$NON-NLS-2$

					//merge user configuration since the base has not changed.
					if (lastKnownBaseTimestamp == sharedConfigTimestamp || lastKnownBaseTimestamp == NO_TIMESTAMP) {
						mergeProperties(System.getProperties(), configuration, null);
					} else {
						configuration = null;
						System.setProperty(PROP_IGNORE_USER_CONFIGURATION, Boolean.TRUE.toString());
					}

					//now merge the base configuration
					mergeProperties(System.getProperties(), sharedConfiguration, 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;
		}
	}

	private long getCurrentConfigIniBaseTimestamp(URL url) {
		try {
			url = new URL(url, CONFIG_FILE);
		} catch (MalformedURLException e1) {
			return NO_TIMESTAMP;
		}
		URLConnection connection = null;
		try {
			connection = url.openConnection();
		} catch (IOException e) {
			return NO_TIMESTAMP;
		}
		return connection.getLastModified();
	}

	//Get the timestamp that has been remembered. The BASE_TIMESTAMP_FILE_CONFIGINI is written at provisioning time by fwkAdmin.
	private long getLastKnownConfigIniBaseTimestamp() {
		if (debug)
			System.out.println("Loading timestamp file from:\n\t " + getConfigurationLocation() + "   " + BASE_TIMESTAMP_FILE_CONFIGINI); //$NON-NLS-1$ //$NON-NLS-2$
		Properties result;
		try {
			result = load(getConfigurationLocation(), BASE_TIMESTAMP_FILE_CONFIGINI);
		} catch (IOException e) {
			if (debug)
				System.out.println("\tNo timestamp file found"); //$NON-NLS-1$
			return NO_TIMESTAMP;
		}
		String timestamp = result.getProperty(KEY_CONFIGINI_TIMESTAMP);
		return Long.parseLong(timestamp);
	}

	/**
	 * 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 substituteVars(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<String> path = new ArrayList<String>(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(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<String> result = new ArrayList<String>(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 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, Properties userConfiguration) {
		final String EXT_OVERRIDE_USER = ".override.user"; //$NON-NLS-1$
		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);

			// Check to see if we are supposed to override existing values from the user configuraiton.
			// This is done only in the case of shared install where we have already set the user values 
			// but want to override them with values from the shared location's config.
			if (userConfiguration != null && !key.endsWith(EXT_OVERRIDE_USER)) {
				// check all levels to see if the "override" property was set
				final String overrideKey = key + EXT_OVERRIDE_USER;
				boolean shouldOverride = destination.getProperty(overrideKey) != null || source.getProperty(overrideKey) != null;
				// only set the value if the user specified the override property and if the 
				// original property wasn't set by a commad-line arg
				if (shouldOverride && !userConfiguration.contains(key)) {
					destination.put(key, value);
					continue;
				}
			}

			// only set the value if it doesn't already exist to preserve ordering (command-line, user config, shared config)
			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<Permission> elements() {
					return new Enumeration<Permission>() {
						int cur = 0;

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

						public Permission 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);
		}
	}

	private Properties substituteVars(Properties result) {
		if (result == null) {
			//nothing todo.
			return null;
		}
		for (Enumeration<?> eKeys = result.keys(); eKeys.hasMoreElements();) {
			Object key = eKeys.nextElement();
			if (key instanceof String) {
				String value = result.getProperty((String) key);
				if (value != null)
					result.put(key, substituteVars(value));
			}
		}
		return result;
	}

	public static String substituteVars(String path) {
		StringBuffer buf = new StringBuffer(path.length());
		StringTokenizer st = new StringTokenizer(path, VARIABLE_DELIM_STRING, true);
		boolean varStarted = false; // indicates we are processing a var subtitute
		String var = null; // the current var key
		while (st.hasMoreElements()) {
			String tok = st.nextToken();
			if (VARIABLE_DELIM_STRING.equals(tok)) {
				if (!varStarted) {
					varStarted = true; // we found the start of a var
					var = ""; //$NON-NLS-1$
				} else {
					// we have found the end of a var
					String prop = null;
					// get the value of the var from system properties
					if (var != null && var.length() > 0)
						prop = System.getProperty(var);
					if (prop == null) {
						try {
							// try using the System.getenv method if it exists (bug 126921)
							Method getenv = System.class.getMethod("getenv", new Class[] {String.class}); //$NON-NLS-1$
							prop = (String) getenv.invoke(null, new Object[] {var});
						} catch (Throwable t) {
							// do nothing; 
							// on 1.4 VMs this throws an error
							// on J2ME this method does not exist
						}
					}
					if (prop != null) {
						// found a value; use it
						buf.append(prop);
					} else {
						// could not find a value append the var; keep delemiters
						buf.append(VARIABLE_DELIM_CHAR);
						buf.append(var == null ? "" : var); //$NON-NLS-1$
						buf.append(VARIABLE_DELIM_CHAR);
					}
					varStarted = false;
					var = null;
				}
			} else {
				if (!varStarted)
					buf.append(tok); // the token is not part of a var
				else
					var = tok; // the token is the var key; save the key to process when we find the end token
			}
		}
		if (var != null)
			// found a case of $var at the end of the path with no trailing $; just append it as is.
			buf.append(VARIABLE_DELIM_CHAR).append(var);
		return buf.toString();
	}
}
