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

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

/**
 * The launcher for Eclipse.
 */
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;
    private boolean splashDown = false;
    public final class SplashHandler extends Thread {
    	public void run() {
    		takeDownSplash();
    	}
    	public void updateSplash() {
			if(bridge != null) {
				bridge.updateSplash();
			}
		}
    }
    private final Thread splashHandler = new SplashHandler();

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

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

    // types of parent classloaders the framework can have
    private static final String PARENT_CLASSLOADER_APP = "app"; //$NON-NLS-1$
    private static final String PARENT_CLASSLOADER_EXT = "ext"; //$NON-NLS-1$
    private static final String PARENT_CLASSLOADER_BOOT = "boot"; //$NON-NLS-1$
    private static final String PARENT_CLASSLOADER_CURRENT = "current"; //$NON-NLS-1$

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

    /**
     * A structured form for a version identifier.
     * 
     * @see http://java.sun.com/j2se/versioning_naming.html for information on valid version strings
     */
    static class Identifier {
        private static final String DELIM = ". _-"; //$NON-NLS-1$
        private int major, minor, service;
        Identifier(int major, int minor, int service) {
            super();
            this.major = major;
            this.minor = minor;
            this.service = service;
        }
        /**
         * @throws NumberFormatException if cannot parse the major and minor version components
         */
        Identifier(String versionString) {
            super();
            StringTokenizer tokenizer = new StringTokenizer(versionString, DELIM);

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

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

            try {
                // service
                if (tokenizer.hasMoreTokens())
                    service = Integer.parseInt(tokenizer.nextToken());
            } catch (NumberFormatException nfe) {
                // ignore the service qualifier in that case and default to 0
                // this will allow us to tolerate other non-conventional version numbers 
            }
        }
        /**
         * Returns true if this id is considered to be greater than or equal to the given baseline.
         * e.g. 
         * 1.2.9 >= 1.3.1 -> false
         * 1.3.0 >= 1.3.1 -> false
         * 1.3.1 >= 1.3.1 -> true
         * 1.3.2 >= 1.3.1 -> true
         * 2.0.0 >= 1.3.1 -> true
         */
        boolean isGreaterEqualTo(Identifier minimum) {
            if (major < minimum.major)
                return false;
            if (major > minimum.major)
                return true;
            // major numbers are equivalent so check minor
            if (minor < minimum.minor)
                return false;
            if (minor > minimum.minor)
                return true;
            // minor numbers are equivalent so check service
            return service >= minimum.service;
        }
    }   

    private String getWS() {
		if (ws != null)
			return ws;
		String os = getOS();
		if (os.equals(Constants.OS_WIN32))
			return Constants.WS_WIN32;
		if (os.equals(Constants.OS_LINUX))
			return Constants.WS_GTK;
		if (os.equals(Constants.OS_MACOSX))
			return Constants.WS_CARBON;
		if (os.equals(Constants.OS_HPUX))
			return Constants.WS_MOTIF;
		if (os.equals(Constants.OS_AIX))
			return Constants.WS_MOTIF;
		if (os.equals(Constants.OS_SOLARIS))
			return Constants.WS_MOTIF;
		if (os.equals(Constants.OS_QNX))
			return Constants.WS_PHOTON;
		return Constants.WS_UNKNOWN;
	}
    private String getOS() {
		if (os != null)
			return os;
		String osName = System.getProperties().getProperty("os.name"); //$NON-NLS-1$
		if (osName.regionMatches(true, 0, Constants.OS_WIN32, 0, 3))
			return Constants.OS_WIN32;
		// EXCEPTION: All mappings of SunOS convert to Solaris
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_SUNOS))
			return Constants.OS_SOLARIS;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_LINUX))
			return Constants.OS_LINUX;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_QNX))
			return Constants.OS_QNX;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_AIX))
			return Constants.OS_AIX;
		if (osName.equalsIgnoreCase(Constants.INTERNAL_OS_HPUX))
			return Constants.OS_HPUX;
		// 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 name = System.getProperties().getProperty("os.arch");//$NON-NLS-1$
		// Map i386 architecture to x86
		if (name.equalsIgnoreCase(Constants.INTERNAL_ARCH_I386))
			return Constants.ARCH_X86;
		// Map amd64 architecture to x86_64
		else if (name.equalsIgnoreCase(Constants.INTERNAL_AMD64))
			return Constants.ARCH_X86_64;

		return name;
	}
    
    /**
	 *  Sets up the JNI bridge to native calls
	 */
	private void setupJNI(URL[] defaultPath) {
		String libPath = null;
		
		if (library != null) {
			File lib = new File(library);
			if(lib.isDirectory()) {
				libPath = searchFor("eclipse", lib.getAbsolutePath()); //$NON-NLS-1$
			} else if(lib.exists()){
				libPath = lib.getAbsolutePath();
			}
		} 
		if(libPath == null) {
			//find our fragment name
			String fragmentOS = getOS();
			StringBuffer buffer = new StringBuffer(PLUGIN_ID);
			buffer.append('.');
			buffer.append(getWS());
			buffer.append('.');
			buffer.append(fragmentOS);
			if(!fragmentOS.equals("macosx")){ //$NON-NLS-1$
				buffer.append('.');
				buffer.append(getArch());
			}
			String fragmentName = buffer.toString();
			String fragment = null;
			if (inDevelopmentMode) {
				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 = searchFor("eclipse", fragment); //$NON-NLS-1$
					}
				}
			}
			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 = searchFor("eclipse", fragment); //$NON-NLS-1$
					}
				}
			}
			if(libPath == null) {
				URL install = getInstallLocation();
				String location = install.getFile();
				location += "/plugins/"; //$NON-NLS-1$
				fragment = searchFor(fragmentName, location);
				if (fragment != null)
					libPath = searchFor("eclipse", fragment); //$NON-NLS-1$
			}
		}
		library = libPath;
		if(library != null)
			bridge = new JNIBridge(library);
	}
    
    /**
     * Executes the launch.
     * 
     * @param args command-line arguments
     * @exception Exception thrown if a problem occurs during the launch
     */
    protected void basicRun(String[] args) throws Exception {
        System.getProperties().put("eclipse.startTime", Long.toString(System.currentTimeMillis())); //$NON-NLS-1$
        commands = args;
        String[] passThruArgs = processCommandLine(args);
        
        if (!debug)
        	// debug can be specified as system property as well
        	debug = System.getProperty(PROP_DEBUG) != null;
        setupVMProperties();
        processConfiguration();
        
        // need to ensure that getInstallLocation is called at least once to initialize the value.
        // Do this AFTER processing the configuration to allow the configuration to set
        // the install location.  
        getInstallLocation();

        // locate boot plugin (may return -dev mode variations)
        URL[] bootPath = getBootPath(bootLocation);
        
        //Set up the JNI bridge.  We need to know the install location to find the shared library
        setupJNI(bootPath);
        
        //ensure minimum Java version, do this after JNI is set up so that we can write an error message 
        //with exitdata if we fail.
        if (!checkVersion(System.getProperty("java.version"), System.getProperty(PROP_REQUIRED_JAVA_VERSION))) //$NON-NLS-1$
            return;
        
        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) {
            SecurityManager sm = System.getSecurityManager();
            boolean setSM = false;
            if (sm == null) {
                if (eclipseSecurity.length() < 1) {
                    eclipseSecurity = "java.lang.SecurityManager"; //$NON-NLS-1$
                }
                try {
                    Class clazz = Class.forName(eclipseSecurity);
                    sm = (SecurityManager) clazz.newInstance();
                    setSM = true;
                }
                catch (Throwable t) {
                	System.getProperties().put("java.security.manager", eclipseSecurity); // let the framework try to load it later. //$NON-NLS-1$
                }
            }
            
            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);
            if (setSM)
                System.setSecurityManager(sm);
        }
    }

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

    /**
     * Checks whether the given available version is greater or equal to the 
     * given required version.
     * <p>Will set PROP_EXITCODE/PROP_EXITDATA accordingly if check fails.</p>
     *   
     * @return a boolean indicating whether the checking passed 
     */
    private boolean checkVersion(String availableVersion, String requiredVersion) {
        if (requiredVersion == null || availableVersion == null)
            return true;
        try {
            Identifier required = new Identifier(requiredVersion);
            Identifier available = new Identifier(availableVersion);
            boolean compatible = available.isGreaterEqualTo(required);
            if (!compatible) {
                // any non-zero value should do it - 14 used to be used for version incompatibility in Eclipse 2.1 
                System.getProperties().put(PROP_EXITCODE, "14"); //$NON-NLS-1$
                System.getProperties().put(PROP_EXITDATA, "<title>Incompatible JVM</title>Version " + availableVersion + " of the JVM is not suitable for this product. Version: "+ requiredVersion + " or greater is required."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            }
            return compatible;
        } catch (SecurityException e) {
            // If the security manager won't allow us to get the system property, continue for
            // now and let things fail later on their own if necessary.
            return true;
        } catch (NumberFormatException e) {
            // If the version string was in a format that we don't understand, continue and
            // let things fail later on their own if necessary.
            return true;
        }
    }
    
    /**
     * Returns a string representation of the given URL String.  This converts
     * escaped sequences (%..) in the URL into the appropriate characters.
     * NOTE: due to class visibility there is a copy of this method
     *       in InternalBootLoader
     */
    protected String decode(String urlString) {
        //try to use Java 1.4 method if available
        try {
            Class clazz = URLDecoder.class;
            Method method = clazz.getDeclaredMethod("decode", new Class[] {String.class, String.class}); //$NON-NLS-1$
            //first encode '+' characters, because URLDecoder incorrectly converts 
            //them to spaces on certain class library implementations.
            if (urlString.indexOf('+') >= 0) {
                int len = urlString.length();
                StringBuffer buf = new StringBuffer(len);
                for (int i = 0; i < len; i++) {
                    char c = urlString.charAt(i);
                    if (c == '+')
                        buf.append("%2B"); //$NON-NLS-1$
                    else
                        buf.append(c);
                }
                urlString = buf.toString();
            }
            Object result = method.invoke(null, new Object[] {urlString, "UTF-8"}); //$NON-NLS-1$
            if (result != null)
                return (String) result;
        } catch (Exception e) {
            //JDK 1.4 method not found -- fall through and decode by hand
        }
        //decode URL by hand
        boolean replaced = false;
        byte[] encodedBytes = urlString.getBytes();
        int encodedLength = encodedBytes.length;
        byte[] decodedBytes = new byte[encodedLength];
        int decodedLength = 0;
        for (int i = 0; i < encodedLength; i++) {
            byte b = encodedBytes[i];
            if (b == '%') {
            	if(i+2 >= encodedLength)
            		throw new IllegalArgumentException("Malformed URL (\""+urlString+"\"): % must be followed by 2 digits.");  //$NON-NLS-1$//$NON-NLS-2$
                byte enc1 = encodedBytes[++i];
                byte enc2 = encodedBytes[++i];
                b = (byte) ((hexToByte(enc1) << 4) + hexToByte(enc2));
                replaced = true;
            }
            decodedBytes[decodedLength++] = b;
        }
        if (!replaced)
            return urlString;
        try {
            return new String(decodedBytes, 0, decodedLength, "UTF-8"); //$NON-NLS-1$
        } catch (UnsupportedEncodingException e) {
            //use default encoding
            return new String(decodedBytes, 0, decodedLength);
        }
    }

    /**
     * Returns the result of converting a list of comma-separated tokens into an array
     * 
     * @return the array of string tokens
     * @param prop the initial comma-separated string
     */
    protected String[] getArrayFromList(String prop) {
        if (prop == null || prop.trim().equals("")) //$NON-NLS-1$
            return new String[0];
        Vector list = new Vector();
        StringTokenizer tokens = new StringTokenizer(prop, ","); //$NON-NLS-1$
        while (tokens.hasMoreTokens()) {
            String token = tokens.nextToken().trim();
            if (!token.equals("")) //$NON-NLS-1$
                list.addElement(token);
        }
        return list.isEmpty() ? new String[0] : (String[]) list.toArray(new String[list.size()]);
    }

    /**
     * Returns the <code>URL</code>-based class path describing where the boot classes
     * are located when running in development mode.
     * 
     * @return the url-based class path
     * @param base the base location
     * @exception MalformedURLException if a problem occurs computing the class path
     */
    private URL[] getDevPath(URL base) throws IOException {
        ArrayList result = new ArrayList(5);
        if (inDevelopmentMode)
            addDevEntries(base, result, OSGI);
        //The jars from the base always need to be added, even when running in dev mode (bug 46772)
        addBaseJars(base, result);
        return (URL[]) result.toArray(new URL[result.size()]);
    }

    URL constructURL(URL url, String name) {
        //Recognize the following URLs
        //url: file:foo/dir/
        //url: file:foo/file.jar
        
        String externalForm = url.toExternalForm();
        if (externalForm.endsWith(".jar")) { //$NON-NLS-1$
            try {
                return new URL(JAR_SCHEME + url + "!/" + name); //$NON-NLS-1$
            } catch (MalformedURLException e) {
                //Ignore
            }
        }
        
        try {
            return new URL(url, name);
        } catch (MalformedURLException e) {
            //Ignore
            return null;
        }
    }
    private void readFrameworkExtensions(URL base, ArrayList result) throws IOException {
        String[] extensions = getArrayFromList(System.getProperties().getProperty(PROP_EXTENSIONS));
        String parent = new File(base.getFile()).getParent().toString();
        ArrayList extensionResults = new ArrayList(extensions.length);
        for (int i = 0; i < extensions.length; i++) {
            //Search the extension relatively to the osgi plugin 
            String path = searchFor(extensions[i], parent);
            if (path == null) {
                log("Could not find extension: " + extensions[i]); //$NON-NLS-1$
                continue;
            }
            if (debug)
                System.out.println("Loading extension: " + extensions[i]); //$NON-NLS-1$

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

            //Load a property file of the extension, merge its content, and in case of dev mode add the bin entries
            Properties extensionProperties = null;
            try {
                extensionProperties = loadProperties(constructURL(extensionURL, ECLIPSE_PROPERTIES));
            } catch (IOException e) {
                if (debug)
                    System.out.println("\t" + ECLIPSE_PROPERTIES + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
            }
            String extensionClassPath = null;
            if (extensionProperties != null)
                extensionClassPath = extensionProperties.getProperty(PROP_CLASSPATH);
            else // this is a "normal" RFC 101 framework extension bundle just put the base path on the classpath
                extensionProperties = new Properties();
            String[] entries = extensionClassPath == null || extensionClassPath.length() == 0 ? new String[] {""} : getArrayFromList(extensionClassPath); //$NON-NLS-1$
            String qualifiedPath;
			if (System.getProperty(PROP_CLASSPATH)==null)
				qualifiedPath = "."; //$NON-NLS-1$
			else
				qualifiedPath = ""; //$NON-NLS-1$
            for (int j = 0; j < entries.length; j++)
                qualifiedPath += ", " + FILE_SCHEME + path + entries[j]; //$NON-NLS-1$
            extensionProperties.put(PROP_CLASSPATH, qualifiedPath);
            mergeProperties(System.getProperties(), extensionProperties);
            if (inDevelopmentMode) 
                addDevEntries(extensionURL, result, extensions[i]);
        }
        extensionPaths = (String[]) extensionResults.toArray(new String[extensionResults.size()]);
    }

    private void addBaseJars(URL base, ArrayList result) throws IOException {
        String baseJarList = System.getProperty(PROP_CLASSPATH);
        if (baseJarList == null) {
            readFrameworkExtensions(base, result);
            baseJarList = System.getProperties().getProperty(PROP_CLASSPATH);
        }
        
        File fwkFile = new File(base.getFile());
        boolean fwkIsDirectory = fwkFile.isDirectory();
        //We found where the fwk is, remember it and its shape
        if (fwkIsDirectory) {
        	System.getProperties().put(PROP_FRAMEWORK_SHAPE, "folder");//$NON-NLS-1$
        } else {
            System.getProperties().put(PROP_FRAMEWORK_SHAPE, "jar");//$NON-NLS-1$
        }
        String fwkPath = new File(new File(base.getFile()).getParent()).getAbsolutePath();
		if (Character.isUpperCase(fwkPath.charAt(0))) {
			char[] chars = fwkPath.toCharArray();
			chars[0] = Character.toLowerCase(chars[0]);
			fwkPath = new String(chars);
		}
        System.getProperties().put(PROP_FRAMEWORK_SYSPATH, fwkPath);
        
        String[] baseJars = getArrayFromList(baseJarList);
        if (baseJars.length == 0) {
            if (!inDevelopmentMode && new File(base.getFile()).isDirectory())
                throw new IOException("Unable to initialize " + PROP_CLASSPATH); //$NON-NLS-1$
            addEntry(base, result);
            return;
        }
        for (int i = 0; i < baseJars.length; i++) {
            String string = baseJars[i];
            try {
                // if the string is a file: URL then *carefully* construct the
                // URL. Otherwisejust try to build a URL. In either case, if we fail, use
                // string as something to tack on the end of the base.
                
                if (string.equals(".")) { //$NON-NLS-1$
                    addEntry(base, result);
                }
                URL url = null;
                if (string.startsWith(FILE_SCHEME))
                    url = new File(string.substring(5)).toURL();
                else
                    url = new URL(string);
                addEntry(url, result);
            } catch (MalformedURLException e) {
                addEntry(new URL(base, string), result);
            }
        }
    }

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

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

    /**
     * Returns the <code>URL</code>-based class path describing where the boot classes are located.
     * 
     * @return the url-based class path
     * @param base the base location
     * @exception MalformedURLException if a problem occurs computing the class path
     */
    protected URL[] getBootPath(String base) throws IOException {
        URL url = null;
        if (base != null) {
            url = buildURL(base, true);
        } else {
            // search in the root location
            url = getInstallLocation();
            String path = new File(url.getFile(), "plugins").toString(); //$NON-NLS-1$
            path = searchFor(framework, path);
            if (path == null)
                throw new RuntimeException("Could not find framework"); //$NON-NLS-1$
            if (url.getProtocol().equals("file")) //$NON-NLS-1$
                url = new File(path).toURL();
            else
                url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
        }
        if (System.getProperty(PROP_FRAMEWORK) == null)
            System.getProperties().put(PROP_FRAMEWORK, url.toExternalForm());
        if (debug)
            System.out.println("Framework located:\n    " + url.toExternalForm()); //$NON-NLS-1$
        // add on any dev path elements
        URL[] result = getDevPath(url);
        if (debug) {
            System.out.println("Framework classpath:"); //$NON-NLS-1$
            for (int i = 0; i < result.length; i++)
                System.out.println("    " + result[i].toExternalForm()); //$NON-NLS-1$
        }
        return result;
    }

    /**
     * Searches for the given target directory starting in the "plugins" subdirectory
     * of the given location.  If one is found then this location is returned; 
     * otherwise an exception is thrown.
     * 
     * @return the location where target directory was found
     * @param start the location to begin searching
     */
    protected String searchFor(final String target, String start) {
    	return searchFor(target, null, start);
    }
    protected String searchFor(final String target, final String targetSuffix, String start) {
    	// Note that File.list only gives you file names not the complete path from start
    	String[] candidates = new File(start).list();
        if (candidates == null)
            return null;
        
		ArrayList matches = new ArrayList(2);
		for (int i = 0; i < candidates.length; i++)
			if (candidates[i].equals(target) || candidates[i].startsWith(target + "_"))  //$NON-NLS-1$
				matches.add(candidates[i]);
		String[] names = (String[]) matches.toArray(new String[matches.size()]);
		int result = findMax(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$
    }

    protected int findMax(String[] candidates) {
        int result = -1;
        Object maxVersion = null;
        for (int i = 0; i < candidates.length; i++) {
            String name = candidates[i];
            String version = ""; //$NON-NLS-1$ // Note: directory with version suffix is always > than directory without version suffix
            int index = name.indexOf('_');
            if (index != -1)
                version = name.substring(index + 1);
            Object currentVersion = getVersionElements(version);
            if (maxVersion == null) {
                result = i;
                maxVersion = currentVersion;
            } else {
                if (compareVersion((Object[]) maxVersion, (Object[]) currentVersion) < 0) {
                    result = i;
                    maxVersion = currentVersion;
                }
            }
        }
        return result;
    }
    /**
     * Compares version strings. 
     * @return result of comparison, as integer;
     * <code><0</code> if left < right;
     * <code>0</code> if left == right;
     * <code>>0</code> if left > right;
     */
    private int compareVersion(Object[] left, Object[] right) {

        int result = ((Integer) left[0]).compareTo((Integer) right[0]); // compare major
        if (result != 0)
            return result;

        result = ((Integer) left[1]).compareTo((Integer) right[1]); // compare minor
        if (result != 0)
            return result;

        result = ((Integer) left[2]).compareTo((Integer) right[2]); // compare service
        if (result != 0)
            return result;

        return ((String) left[3]).compareTo((String) right[3]); // compare qualifier
    }

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

    private static URL buildURL(String spec, boolean trailingSlash) {
        if (spec == null)
            return null;
        boolean isFile = spec.startsWith(FILE_SCHEME);
        try {
            if (isFile) {
                File toAdjust = new File(spec.substring(5));
                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;
            }
        }
    }

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

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

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

    /** 
     * Retuns the default file system path for the configuration location.
     * By default the configuration information is in the installation directory
     * if this is writeable.  Otherwise it is located somewhere in the user.home
     * area relative to the current product. 
     * @return the default file system path for the configuration information
     */
    private String computeDefaultConfigurationLocation() {
        // 1) We store the config state relative to the 'eclipse' directory if possible
        // 2) If this directory is read-only 
        //    we store the state in <user.home>/.eclipse/<application-id>_<version> where <user.home> 
        //    is unique for each local user, and <application-id> is the one 
        //    defined in .eclipseproduct marker file. If .eclipseproduct does not
        //    exist, use "eclipse" as the application-id.

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

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

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

        File fileTest = null;
        try {
        	// we use the .dll suffix to properly test on Vista virtual directories
        	// on Vista you are not allowed to write executable files on virtual directories like "Program Files"
            fileTest = File.createTempFile("writtableArea", ".dll", installDir); //$NON-NLS-1$ //$NON-NLS-2$
        } catch (IOException e) {
            //If an exception occured while trying to create the file, it means that it is not writtable
            return false;
        } finally {
            if (fileTest != null)
                fileTest.delete();
        }
        return true;
    }
    
    /**
     * Returns a files system path for an area in the user.home region related to the
     * current product.  The given appendage is added to this base location
     * @param pathAppendage the path segments to add to computed base
     * @return a file system location in the user.home area related the the current
     *   product and the given appendage
     */
    private String computeDefaultUserAreaLocation(String pathAppendage) {
        //    we store the state in <user.home>/.eclipse/<application-id>_<version> where <user.home> 
        //    is unique for each local user, and <application-id> is the one 
        //    defined in .eclipseproduct marker file. If .eclipseproduct does not
        //    exist, use "eclipse" as the application-id.
        URL installURL = getInstallLocation();
        if (installURL == null)
            return null;
        File installDir = new File(installURL.getFile());
        // compute an install dir hash to prevent configuration area collisions with other eclipse installs
        int hashCode;
        try {
        	hashCode = installDir.getCanonicalPath().hashCode();
        } catch (IOException ioe) {
        	// fall back to absolute path
        	hashCode = installDir.getAbsolutePath().hashCode();
        }
       	if (hashCode < 0)
       		hashCode = -(hashCode);
       	String installDirHash = String.valueOf(hashCode);

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

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

    /**
     * Runs the platform with the given arguments.  The arguments must identify
     * an application to run (e.g., <code>-application com.example.application</code>).
     * After running the application <code>System.exit(N)</code> is executed.
     * The value of N is derived from the value returned from running the application.
     * If the application's return value is an <code>Integer</code>, N is this value.
     * In all other cases, N = 0.
     * <p>
     * Clients wishing to run the platform without a following <code>System.exit</code>
     * call should use <code>run()</code>.
     * </p>
     * 
     * @param args the command line arguments
     * @see #run(String[])
     */
	public static void main(String[] args) {
		int result = 0;
		try {
			result = new Main().run(args);
		} catch (Throwable t) {
			// This is *really* unlikely to happen - run() takes care of exceptional situations.
			// In case something weird happens, just dump stack - logging is not available at this point
			t.printStackTrace();
		} finally {
			if (!Boolean.getBoolean(PROP_NOSHUTDOWN))
			// make sure we always terminate the VM
				System.exit(result);
		}
	}


    /**
     * Runs the platform with the given arguments.  The arguments must identify
     * an application to run (e.g., <code>-application com.example.application</code>).
     * Returns the value returned from running the application.
     * If the application's return value is an <code>Integer</code>, N is this value.
     * In all other cases, N = 0.
     *
     * @param args the command line arguments
     */
    public int run(String[] args) {
        int result = 0;
        try {
            basicRun(args);
            String exitCode = System.getProperty(PROP_EXITCODE);
            try {
                result = exitCode == null ? 0 : Integer.parseInt(exitCode);
            } catch (NumberFormatException e) {
                result = 17;
            }
        } catch (Throwable e) {
            // only log the exceptions if they have not been caught by the 
            // EclipseStarter (i.e., if the exitCode is not 13) 
            if (!"13".equals(System.getProperty(PROP_EXITCODE))) { //$NON-NLS-1$
                log("Exception launching the Eclipse Platform:"); //$NON-NLS-1$
                log(e);
                String message = "An error has occurred"; //$NON-NLS-1$
                if (logFile == null)
                    message += " and could not be logged: \n" + e.getMessage(); //$NON-NLS-1$
                else
                    message += ".  See the log file\n" + logFile.getAbsolutePath(); //$NON-NLS-1$
                System.getProperties().put(PROP_EXITDATA, message);
            }
            // Return "unlucky" 13 as the exit code. The executable will recognize
            // this constant and display a message to the user telling them that
            // there is information in their log file.
            result = 13;
        } finally {
            // always try putting down the splash screen just in case the application failed to do so
            takeDownSplash();           
            if(bridge != null)
            	bridge.uninitialize();
        }
        // Return an int exit code and ensure the system property is set.
        System.getProperties().put(PROP_EXITCODE, Integer.toString(result));
        setExitData();
        return result;
    }

    private void setExitData() {
        String data = System.getProperty(PROP_EXITDATA);
        if (data == null || bridge == null)
            return;
        bridge.setExitData(exitData, data);
    }
    
    /**
     * Processes the command line arguments.  The general principle is to NOT
     * consume the arguments and leave them to be processed by Eclipse proper.
     * There are a few args which are directed towards main() and a few others
     * which we need to know about. Very few should actually be consumed here.
     * 
     * @return the arguments to pass through to the launched application
     * @param args the command line arguments
     */
    protected String[] processCommandLine(String[] args) {
        if (args.length == 0)
            return args;
        int[] configArgs = new int[args.length];
        configArgs[0] = -1; // need to initialize the first element to something that could not be an index.
        int configArgIndex = 0;
        for (int i = 0; i < args.length; i++) {
            boolean found = false;
            // check for args without parameters (i.e., a flag arg)
            // check if debug should be enabled for the entire platform
            if (args[i].equalsIgnoreCase(DEBUG)) {
                debug = true;
                // passed thru this arg (i.e., do not set found = true)
                continue;
            }

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

            if (args[i].equalsIgnoreCase(NOEXIT)) {
            	System.getProperties().put(PROP_NOSHUTDOWN, "true"); //$NON-NLS-1$
            	found = true;
            }
            
            // check if this is initialization pass
            if (args[i].equalsIgnoreCase(INITIALIZE)) {
                initialize = true;
                // passed thru this arg (i.e., do not set found = true)
                continue;
            }

            // check if development mode should be enabled for the entire platform
            // If this is the last arg or there is a following arg (i.e., arg+1 has a leading -), 
            // simply enable development mode.  Otherwise, assume that that the following arg is
            // actually some additional development time class path entries.  This will be processed below.
            if (args[i].equalsIgnoreCase(DEV) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) { //$NON-NLS-1$
                inDevelopmentMode = true;
                // do not mark the arg as found so it will be passed through
                continue;
            }

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

            // look for the VM args arg.  We have to do that before looking to see
            // if the next element is a -arg as the thing following -vmargs may in
            // fact be another -arg.
            if (args[i].equalsIgnoreCase(VMARGS)) {
                // consume the -vmargs arg itself
                args[i] = null;
                i++;
                vmargs = new String[args.length - i];
                for (int j = 0; i < args.length; i++) {
                    vmargs[j++] = args[i];
                    args[i] = null;
                }
                continue;
            }

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

            // look for the development mode and class path entries.  
            if (args[i - 1].equalsIgnoreCase(DEV)) {
                inDevelopmentMode = true;
                devClassPathProps = processDevArg(arg);
                if (devClassPathProps != null) {
                	devClassPath = devClassPathProps.getProperty(OSGI);
                	if (devClassPath == null)
                		devClassPath = devClassPathProps.getProperty("*"); //$NON-NLS-1$
                }
                continue;
            }

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

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

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

            if (args[i - 1].equalsIgnoreCase(EXITDATA)) {
            	exitData = arg;
            	found = true;
            }
            
            // look for the name to use by the launcher
            if (args[i - 1].equalsIgnoreCase(NAME)) {
            	//not doing anything with this right now, but still consume it
                //name = 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;
                found = true;
            }
            
            if (args[i - 1].equalsIgnoreCase(LIBRARY)) {
            	library = arg;
            	found = true;
            }
            
            // look for the command to use to end the splash screen
            if (args[i - 1].equalsIgnoreCase(ENDSPLASH)) {
                endSplash = arg;
                found = true;
            }

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

			//look for the nl setting
			if (args[i - 1].equalsIgnoreCase(NL)) {
				System.getProperties().put(PROP_NL, arg);
				found = true;
			}
			
            // done checking for args.  Remember where an arg was found 
            if (found) {
                configArgs[configArgIndex++] = i - 1;
                configArgs[configArgIndex++] = i;
            }
        }
        // remove all the arguments consumed by this argument parsing
        String[] passThruArgs = new String[args.length - configArgIndex - (vmargs == null ? 0 : vmargs.length + 1)];
        configArgIndex = 0;
        int j = 0;
        for (int i = 0; i < args.length; i++) {
            if (i == configArgs[configArgIndex])
                configArgIndex++;
            else if (args[i] != null)
                passThruArgs[j++] = args[i];
        }
        return passThruArgs;
    }

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

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

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

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

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

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

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

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

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

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

    /*
     * Load the configuration  
     */
    private Properties load(URL url, String suffix) throws IOException {
        // figure out what we will be loading
        if (suffix != null && !suffix.equals("")) //$NON-NLS-1$
            url = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + suffix);

        // try to load saved configuration file
        Properties props = new Properties();
        InputStream is = null;
        try {
            is = url.openStream();
            props.load(is);
        } finally {
            if (is != null)
                try {
                    is.close();
                } catch (IOException e) {
                    //ignore failure to close
                }
        }
        return props;
    }

    /*
     * Handle splash screen.
     * We support 2 startup scenarios:
     * 
     * (1) the executable launcher put up the splash screen. In that
     *     scenario we are invoked with -endsplash command which is
     *     fully formed to take down the splash screen
     * 
     * (2) the executable launcher did not put up the splash screen,
     *     but invokes Eclipse with partially formed -showsplash command.
     *     In this scenario we determine which splash to display (based on 
     *     feature information) and then call -showsplash command. 
     * 
     * In both scenarios we pass a handler (Runnable) to the platform.
     * The handler is called as a result of the launched application calling
     * Platform.endSplash(). In the first scenario this results in the
     * -endsplash command being executed. In the second scenario this
     * results in the process created as a result of the -showsplash command
     * being destroyed.
     * 
     * @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.showSplash(splashLocation);
    	long handle = bridge.getSplashHandle();
    	if(handle != 0 && handle != -1) {
    		System.setProperty("org.eclipse.equinox.launcher.splash.handle", String.valueOf(handle)); //$NON-NLS-1$
    		System.setProperty("org.eclipse.equinox.launcher.splash.location", splashLocation); //$NON-NLS-1$
    		bridge.updateSplash();
    	}
    }

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

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

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

        // can't find it on the splashPath so look for a default splash
        String temp = bootPath[0].getFile(); // take the first path element
        temp = temp.replace('/', File.separatorChar);
        int ix = temp.lastIndexOf("plugins" + File.separator); //$NON-NLS-1$
        if (ix != -1) {
            int pix = temp.indexOf(File.separator, ix + 8);
            if (pix != -1) {
                temp = temp.substring(0, pix);
                result = searchForSplash(new String[] {temp});
                if (result != null)
                    System.getProperties().put(PROP_SPLASHLOCATION, result);
            }
        }
        return result;
    }

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

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

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

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

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

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

	/*
	 * Return a boolean value indicating whether or not the given
	 * path represents a JAR file.
	 */
	private boolean isJAR(String path) {
		if (path.endsWith(File.separator))
			return false;
		int index = path.lastIndexOf('.');
		if (index == -1)
			return false;
		index++;
		// handle the case where we have a '.' at the end
		if (index >= path.length()) 
			return false;
		return "JAR".equalsIgnoreCase(path.substring(index)); //$NON-NLS-1$
	}

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

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

    /*
     * Entry point for logging.
     */
    protected synchronized void log(Object obj) {
        if (obj == null)
            return;
        try {
            openLogFile();
            try {
                if (newSession) {
                    log.write(SESSION);
                    log.write(' ');
                    String timestamp = new Date().toString();
                    log.write(timestamp);
                    log.write(' ');
                    for (int i = SESSION.length() + timestamp.length(); i < 78; i++)
                        log.write('-');
                    log.newLine();
                    newSession = false;
                }
                write(obj);
            } finally {
                if (logFile == null) {
                    if (log != null)
                        log.flush();
                } else
                    closeLogFile();
            }
        } catch (Exception e) {
            System.err.println("An exception occurred while writing to the platform log:"); //$NON-NLS-1$
            e.printStackTrace(System.err);
            System.err.println("Logging to the console instead."); //$NON-NLS-1$
            //we failed to write, so dump log entry to console instead
            try {
                log = logForStream(System.err);
                write(obj);
                log.flush();
            } catch (Exception e2) {
                System.err.println("An exception occurred while logging to the console:"); //$NON-NLS-1$
                e2.printStackTrace(System.err);
            }
        } finally {
            log = null;
        }
    }

    /*
     * This should only be called from #log()
     */
    private void write(Object obj) throws IOException {
        if (obj == null)
            return;
        if (obj instanceof Throwable) {
            log.write(STACK);
            log.newLine();
            ((Throwable) obj).printStackTrace(new PrintWriter(log));
        } else {
            log.write(ENTRY);
            log.write(' ');
            log.write(PLUGIN_ID);
            log.write(' ');
            log.write(String.valueOf(ERROR));
            log.write(' ');
            log.write(String.valueOf(0));
            log.write(' ');
            log.write(getDate(new Date()));
            log.newLine();
            log.write(MESSAGE);
            log.write(' ');
            log.write(String.valueOf(obj));
        }
        log.newLine();
    }

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

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

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

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

    /**
     * Converts an ASCII character representing a hexadecimal
     * value into its integer equivalent.
     */
    private int hexToByte(byte b) {
        switch (b) {
            case '0' :
                return 0;
            case '1' :
                return 1;
            case '2' :
                return 2;
            case '3' :
                return 3;
            case '4' :
                return 4;
            case '5' :
                return 5;
            case '6' :
                return 6;
            case '7' :
                return 7;
            case '8' :
                return 8;
            case '9' :
                return 9;
            case 'A' :
            case 'a' :
                return 10;
            case 'B' :
            case 'b' :
                return 11;
            case 'C' :
            case 'c' :
                return 12;
            case 'D' :
            case 'd' :
                return 13;
            case 'E' :
            case 'e' :
                return 14;
            case 'F' :
            case 'f' :
                return 15;
            default :
                throw new IllegalArgumentException("Switch error decoding URL"); //$NON-NLS-1$
        }
    }

    private void openLogFile() throws IOException {
        computeLogFileLocation();
        try {
            log = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logFile.getAbsolutePath(), true), "UTF-8")); //$NON-NLS-1$
        } catch (IOException e) {
            logFile = null;
            throw e;
        }
    }

    private BufferedWriter logForStream(OutputStream output) {
        try {
            return new BufferedWriter(new OutputStreamWriter(output, "UTF-8")); //$NON-NLS-1$
        } catch (UnsupportedEncodingException e) {
            return new BufferedWriter(new OutputStreamWriter(output));
        }
    }

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

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

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

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

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

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

        // The AllPermissions collection
        private PermissionCollection allPermissions;

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

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

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

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

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

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

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

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

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

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

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

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

    private class StartupClassLoader extends URLClassLoader {

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

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

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

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