/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     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.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
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 {
		@Override
		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_GTK;
		if (osName.equals(Constants.OS_AIX))
			return Constants.WS_GTK;
		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 getOS() {
		if (os != null)
			return os;
		String osgiOs = System.getProperty(PROP_OS);
		if (osgiOs != null) {
			os = osgiOs;
			return os;
		}
		String osName = System.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.getProperty("os.arch");//$NON-NLS-1$
		// Map amd64 architecture to x86_64
		if (name.equalsIgnoreCase(Constants.INTERNAL_AMD64))
			return Constants.ARCH_X86_64;

		return name;
	}

	private String getFragmentString(String fragmentOS, String fragmentWS, String fragmentArch) {
		StringBuilder buffer = new StringBuilder(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);
		}
		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.setProperty("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, Integer.toString(14));
			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 | NumberFormatException 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.
			// 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();
		@SuppressWarnings("resource")
		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.setProperty(PROP_EXITCODE, "14"); //$NON-NLS-1$
				System.setProperty(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 | NumberFormatException 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.
			// 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.parseBoolean(System.getProperty(PROP_CONFIG_AREA + READ_ONLY_AREA_SUFFIX))) {
			// user wants readonly config area
			return true;
		}
		File configDir = new File(locationUrl.getFile()).getAbsoluteFile();
		if (!configDir.exists()) {
			configDir.mkdirs();
			if (!configDir.exists()) {
				System.setProperty(PROP_EXITCODE, "15"); //$NON-NLS-1$
				System.setProperty(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.setProperty(PROP_EXITCODE, "15"); //$NON-NLS-1$
			System.setProperty(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 {
			//first encode '+' characters, because URLDecoder incorrectly converts 
			//them to spaces on certain class library implementations.
			if (urlString.indexOf('+') >= 0) {
				int len = urlString.length();
				StringBuilder buf = new StringBuilder(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();
			}
			return URLDecoder.decode(urlString, "UTF-8"); //$NON-NLS-1$
		} catch (UnsupportedEncodingException e) {
			throw new IllegalArgumentException(e.getMessage());
		}
	}

	/**
	 * 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];
		ArrayList<String> list = new ArrayList<>();
		StringTokenizer tokens = new StringTokenizer(prop, ","); //$NON-NLS-1$
		while (tokens.hasMoreTokens()) {
			String token = tokens.nextToken().trim();
			if (!token.isEmpty()) {
				list.add(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<>(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.getProperty(PROP_EXTENSIONS));
		String parent = new File(base.getFile()).getParent();
		ArrayList<String> extensionResults = new ArrayList<>(extensions.length);
		for (String extension : extensions) {
			//Search the extension relatively to the osgi plugin
			String path = searchForBundle(extension, parent);
			if (path == null) {
				log("Could not find extension: " + extension); //$NON-NLS-1$
				continue;
			}
			if (debug) {
				System.out.println("Loading extension: " + extension); //$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 (String entry : entries) {
				qualifiedPath += ", " + FILE_SCHEME + path + entry; //$NON-NLS-1$
			}
			extensionProperties.put(PROP_CLASSPATH, qualifiedPath);
			mergeWithSystemProperties(extensionProperties, null);
			if (inDevelopmentMode) {
				String name = extension;
				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.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.setProperty(PROP_FRAMEWORK_SHAPE, "folder");//$NON-NLS-1$
		} else {
			System.setProperty(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.setProperty(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 (String string : baseJars) {
			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 (String location : locations) {
			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
	 */
	private 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 pluginsLocation = new File(url.getFile(), "plugins").toString(); //$NON-NLS-1$
			String path = searchFor(framework, pluginsLocation);
			if (path == null)
				throw new FileNotFoundException(String.format("Could not find framework under %s", pluginsLocation)); //$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.setProperty(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 (URL devPath : result) {
				System.out.println("    " + devPath.toExternalForm()); //$NON-NLS-1$
			}
		}
		return result;
	}

	/**
	 * Searches for the given target directory starting in the "plugins" subdirectory
	 * of the given location.
	 * 
	 * @return the location where target directory was found, <code>null</code> otherwise
	 * @param start the location to begin searching
	 */
	protected String searchFor(final String target, 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<>(2);
		for (String candidate : candidates) {
			if (isMatchingCandidate(target, candidate, root)) {
				matches.add(candidate);
			}
		}
		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 = {Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(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++] = Integer.valueOf(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.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.clearProperty(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.setProperty(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) {
		return installDir.isDirectory() && Files.isWritable(installDir.toPath());
	}

	/**
	 * 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);
		return String.valueOf(hashCode);
	}

	/**
	 * Runs this launcher with the arguments specified in the given string.
	 * 
	 * @param argString the arguments string
	 */
	public static void main(String argString) {
		ArrayList<String> list = new ArrayList<>(5);
		for (StringTokenizer tokens = new StringTokenizer(argString, " "); tokens.hasMoreElements();) //$NON-NLS-1$
			list.add(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.setProperty(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.clearProperty(PROP_SHARED_CONFIG_AREA);
			configuration.remove(PROP_SHARED_CONFIG_AREA);
			mergeWithSystemProperties(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.clearProperty(PROP_SHARED_CONFIG_AREA);
					mergeWithSystemProperties(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) {
						mergeWithSystemProperties(configuration, null);
					} else {
						configuration = null;
						System.setProperty(PROP_IGNORE_USER_CONFIGURATION, Boolean.TRUE.toString());
					}

					//now merge the base configuration
					mergeWithSystemProperties(sharedConfiguration, configuration);
					System.setProperty(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.setProperty(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.setProperty(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.setProperty(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);
		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.setProperty(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); //$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();
		try (InputStream is = getStream(url)) {
			props.load(is);
		}
		return props;
	}

	private InputStream getStream(URL location) throws IOException {
		if ("file".equalsIgnoreCase(location.getProtocol())) { //$NON-NLS-1$
			// this is done to handle URLs with invalid syntax in the path
			File f = new File(location.getPath());
			if (f.exists()) {
				return new FileInputStream(f);
			}
		}
		return location.openStream();
	}

	/*
	 * 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.setProperty(SPLASH_HANDLE, String.valueOf(handle));
			System.setProperty(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.clearProperty(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.setProperty(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<>(entries.length);
			for (String e : entries) {
				String entry = resolve(e);
				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: " + e); //$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.setProperty(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 = System.getProperty(PROP_NL);
		if (locale == null)
			locale = Locale.getDefault().toString();
		String[] nlVariants = buildNLVariants(locale);

		for (String nlVariant : nlVariants) {
			for (String path : searchPath) {
				if (path.startsWith(FILE_SCHEME))
					path = path.substring(5);
				// do we have a JAR?
				if (isJAR(path)) {
					String result = extractFromJAR(path, nlVariant);
					if (result != null)
						return result;
				} else {
					// we have a file or a directory
					if (!path.endsWith(File.separator))
						path += File.separator;
					path += nlVariant;
					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;
	}

	/*
	 * 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 (String command : commands) {
				if (CLEAN.equalsIgnoreCase(command)) {
					clean = true;
					splash.delete();
					break;
				}
			}
			if (!clean)
				return splash.getAbsolutePath();
		}

		try (ZipFile file = new ZipFile(jarPath)) {
			ZipEntry entry = file.getEntry(jarEntry.replace(File.separatorChar, '/'));
			if (entry == null)
				return null;

			Path outputFile = splash.toPath();
			Files.createDirectories(outputFile.getParent());

			try (InputStream input = file.getInputStream(entry)) {
				Files.copy(input, outputFile);
			} catch (IOException e) {
				log("Exception opening splash: " + entry.getName() + " in JAR file: " + jarPath); //$NON-NLS-1$ //$NON-NLS-2$
				log(e);
				return null;
			}

			return splash.exists() ? splash.getAbsolutePath() : null;
		} catch (IOException e) {
			log("Exception looking for " + jarEntry + " in JAR file: " + jarPath); //$NON-NLS-1$ //$NON-NLS-2$
			log(e);
			return 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<>(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);
		StringBuilder sb = new StringBuilder();
		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 StringBuilder appendPaddedInt(int value, int pad, StringBuilder buffer) {
		pad = pad - 1;
		if (pad == 0)
			return buffer.append(value);
		int padding = (int) Math.pow(10, pad);
		if (value >= padding)
			return buffer.append(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(), System.currentTimeMillis() + ".log"); //$NON-NLS-1$
		new File(logFile.getParent()).mkdirs();
		System.setProperty(PROP_LOGFILE, logFile.getAbsolutePath());
	}

	private void openLogFile() throws IOException {
		computeLogFileLocation();
		try {
			log = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath(), true), StandardCharsets.UTF_8));
		} catch (IOException e) {
			logFile = null;
			throw e;
		}
	}

	private BufferedWriter logForStream(OutputStream output) {
		return new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
	}

	private void closeLogFile() throws IOException {
		try {
			if (log != null) {
				log.flush();
				log.close();
			}
		} finally {
			log = null;
		}
	}

	private void mergeWithSystemProperties(Properties source, Properties userConfiguration) {
		final String EXT_OVERRIDE_USER = ".override.user"; //$NON-NLS-1$
		if (source == null)
			return;
		for (Enumeration<?> e = source.keys(); e.hasMoreElements();) {
			String key = (String) e.nextElement();
			if (key.equals(PROP_CLASSPATH)) {
				String destinationClasspath = System.getProperty(PROP_CLASSPATH);
				String sourceClasspath = source.getProperty(PROP_CLASSPATH);
				if (destinationClasspath == null)
					destinationClasspath = sourceClasspath;
				else
					destinationClasspath = destinationClasspath + sourceClasspath;
				System.setProperty(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 = System.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)) {
					System.setProperty(key, value);
					continue;
				}
			}

			// only set the value if it doesn't already exist to preserve ordering (command-line, user config, shared config)
			if (System.getProperty(key) == null)
				System.setProperty(key, value);
		}
	}

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

	private void setMultiValueProperty(String property, String[] values) {
		if (values != null) {
			StringBuilder result = new StringBuilder(300);
			for (String value : values) {
				if (value != null) {
					result.append(value);
					result.append('\n');
				}
			}
			System.setProperty(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
				@Override
				public void add(Permission permission) {
					//no adding to this policy
				}

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

				@Override
				public Enumeration<Permission> elements() {
					return new Enumeration<Permission>() {
						int cur = 0;

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

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

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

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

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

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

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

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

		@Override
		protected String findLibrary(String name) {
			if (extensionPaths == null)
				return super.findLibrary(name);
			String libName = System.mapLibraryName(name);
			for (String extensionPath : extensionPaths) {
				File libFile = new File(extensionPath, libName);
				if (libFile.isFile())
					return libFile.getAbsolutePath();
			}
			return super.findLibrary(name);
		}

		/**
		 * Must override addURL to make it public so the framework can
		 * do deep reflection to add URLs on Java 9.
		 */
		@Override
		public void addURL(URL url) {
			super.addURL(url);
		}

		// preparing for Java 9
		protected URL findResource(String moduleName, String name) {
			return findResource(name);
		}

		// preparing for Java 9
		protected Class<?> findClass(String moduleName, String name) {
			try {
				return findClass(name);
			} catch (ClassNotFoundException e) {
				return null;
			}
		}
	}

	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) {
		StringBuilder buf = new StringBuilder(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) {
						prop = System.getenv(var);
					}
					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();
	}
}
