diff --git a/update/org.eclipse.update.configurator/.classpath b/update/org.eclipse.update.configurator/.classpath
new file mode 100644
index 0000000..065ac06
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/update/org.eclipse.update.configurator/.cvsignore b/update/org.eclipse.update.configurator/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/update/org.eclipse.update.configurator/.options b/update/org.eclipse.update.configurator/.options
new file mode 100644
index 0000000..403dd4a
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.options
@@ -0,0 +1,8 @@
+# Debugging options for the org.eclipse.update.configurator plugin
+
+# Turn on general debugging for the plugin.
+org.eclipse.update.configurator/debug=false
+
+# Turns on debug for the plugin converter.
+org.eclipse.update.configurator/converter/debug=false
+
diff --git a/update/org.eclipse.update.configurator/.project b/update/org.eclipse.update.configurator/.project
new file mode 100644
index 0000000..d860656
--- /dev/null
+++ b/update/org.eclipse.update.configurator/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.update.configurator</name>
+	<comment></comment>
+	<projects>
+		<project>org.eclipse.core.boot</project>
+		<project>org.eclipse.core.runtime</project>
+		<project>org.eclipse.core.runtime.osgi</project>
+		<project>org.eclipse.osgi</project>
+		<project>org.eclipse.osgi.util</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/update/org.eclipse.update.configurator/META-INF/MANIFEST.MF b/update/org.eclipse.update.configurator/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1a3bc9b
--- /dev/null
+++ b/update/org.eclipse.update.configurator/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Bundle-Name: org.eclipse.update.configurator
+Bundle-GlobalName: org.eclipse.update.configurator
+Bundle-Description: Eclipse Update Configurator
+Bundle-Copyright: Open Source Materials - Eclipse 
+Bundle-Version: 3.0.0
+Bundle-DocUrl: http://www.eclipse.org
+Build-Information: ${build-information}
+Bundle-Activator: 
+ org.eclipse.update.configurator.ConfigurationActivator
+Bundle-ClassPath: 
+ configurator.jar
+Import-Package: 
+ org.osgi.framework,
+ org.osgi.util.tracker,
+ org.osgi.service.startlevel,
+ org.osgi.service.packageadmin,
+ org.eclipse.osgi.service.environment
+Export-Package:
+ org.eclipse.update.configurator
+Provide-Package: 
+ org.eclipse.update.configurator
+Require-Bundle: 
+ org.eclipse.core.runtime.osgi,
+ org.apache.xerces;optional=true
diff --git a/update/org.eclipse.update.configurator/build.properties b/update/org.eclipse.update.configurator/build.properties
new file mode 100644
index 0000000..26fc617
--- /dev/null
+++ b/update/org.eclipse.update.configurator/build.properties
@@ -0,0 +1,6 @@
+bin.includes = .options,\
+               plugin.properties,\
+               plugin.xml,\
+               configurator.jar,\
+               META-INF/
+source.configurator.jar = src/
diff --git a/update/org.eclipse.update.configurator/plugin.properties b/update/org.eclipse.update.configurator/plugin.properties
new file mode 100644
index 0000000..22d0828
--- /dev/null
+++ b/update/org.eclipse.update.configurator/plugin.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+pluginName= Install/Update Core
+providerName= Eclipse.org
+fragmentNameWin= Install/Update Core for Windows
+fragmentNameLinux= Install/Update Core for Linux
+
+
diff --git a/update/org.eclipse.update.configurator/plugin.xml b/update/org.eclipse.update.configurator/plugin.xml
new file mode 100644
index 0000000..fbeb811
--- /dev/null
+++ b/update/org.eclipse.update.configurator/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin
+  name="%pluginName"
+  id="org.eclipse.update.configurator"
+  version="3.0.0"
+  provider-name="%providerName">
+
+  <runtime>
+    <library name="configurator.jar">
+      <export name="*"/>
+    </library>   
+  </runtime>
+
+  <requires>
+    <import plugin="org.eclipse.osgi"/>
+    <import plugin="org.eclipse.osgi.util"/>
+    <import plugin="org.eclipse.core.runtime.osgi"/>
+  </requires>
+</plugin>
\ No newline at end of file
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfigurationActivator.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfigurationActivator.java
new file mode 100644
index 0000000..8c620c6
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/ConfigurationActivator.java
@@ -0,0 +1,368 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.osgi.service.environment.DebugOptions;
+import org.eclipse.osgi.service.environment.EnvironmentInfo;
+import org.osgi.framework.*;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ConfigurationActivator implements BundleActivator {
+	private final static String DEFAULT_CONVERTER = "org.eclipse.update.configurator.migration.PluginConverter"; //$NON-NLS-1$
+	public static String PI_CONFIGURATOR = "org.eclipse.update.configurator";
+	// debug options
+	public static String OPTION_DEBUG = PI_CONFIGURATOR + "/debug";
+	public static String OPTION_DEBUG_CONVERTER = PI_CONFIGURATOR + "/converter/debug";
+	// debug values
+	public static boolean DEBUG = false;
+	public static boolean DEBUG_CONVERTER = false;
+
+	private static BundleContext context;
+	private ServiceTracker platformTracker;
+	private ServiceRegistration configurationFactorySR;
+	private String[] allArgs;
+
+	// location used to put the generated manfests
+	private String cacheLocation = (String) System.getProperties().get("osgi.manifest.cache"); //PASCAL Need to set this value somewhere (probably from boot)
+	private IPluginConverter converter;
+	private Set ignore;
+	private BundleListener reconcilerListener;
+	private IPlatform platform;
+	private PlatformConfiguration configuration;
+
+	public void start(BundleContext ctx) throws Exception {
+		context = ctx;
+		obtainArgs();
+		initialize();
+		//Short cut, if the configuration has not changed
+		String application = configuration.getApplicationIdentifier();
+
+		//TODO Hack until PDE changes the default application that they are setting
+		if("org.eclipse.ui.workbench".equals(System.getProperties().get("eclipse.application"))) { //$NON-NLS-1$ //$NON-NLS-2$
+			System.setProperty("eclipse.application", "org.eclipse.ui.ide.workbench"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		if (!(application.equals(PlatformConfiguration.RECONCILER_APP) || System.getProperties().get("osgi.dev") != null))
+			if (System.getProperty("eclipse.application") == null) {
+				System.setProperty("eclipse.application", application);
+				return;
+			}
+		loadOptions();
+		if (DEBUG)
+			System.out.println("Starting update configurator...");
+		computeIgnoredBundles();
+		loadConverter();
+		installBundles();
+	}
+
+	private void initialize() {
+		platform = acquirePlatform();
+		String metaPath = platform.getLocation().append(".metadata").toOSString();
+		URL installURL = platform.getInstallURL();
+		configurationFactorySR = context.registerService(IPlatformConfigurationFactory.class.getName(), new PlatformConfigurationFactory(), null);
+		configuration = getPlatformConfiguration(allArgs, metaPath, installURL);
+	}
+
+	private void computeIgnoredBundles() {
+		String ignoreList = System.getProperty("eclipse.ignore", "org.eclipse.osgi,org.eclipse.core.boot,org.eclipse.core.runtime.adaptor");
+		ignore = new HashSet();
+		StringTokenizer tokenizer = new StringTokenizer(ignoreList, ",");
+		while (tokenizer.hasMoreTokens())
+			ignore.add(tokenizer.nextToken().trim());
+	}
+	private boolean shouldIgnore(String bundleName) {
+		if (ignore == null)
+			return false;
+		StringTokenizer tokenizer = new StringTokenizer(bundleName, "._");
+		String partialName = "";
+		while (tokenizer.hasMoreTokens()) {
+			partialName += tokenizer.nextToken();
+			if (ignore.contains(partialName))
+				return true;
+			partialName += ".";
+		}
+		return false;
+	}
+	private void loadConverter() {
+		// TODO look at making this an extension
+		String converterClassName = System.getProperty("eclipse.manifestconverter", DEFAULT_CONVERTER);
+		if (converterClassName == null)
+			return;
+		Class converterClass;
+		try {
+			converterClass = Class.forName(converterClassName);
+		} catch (ClassNotFoundException e) {
+			return;
+		}
+		try {
+			converter = (IPluginConverter) converterClass.newInstance();
+		} catch (InstantiationException e1) {
+			return;
+		} catch (IllegalAccessException e1) {
+			return;
+		} catch (ClassCastException cce) {
+			return;
+		}
+	}
+	private void obtainArgs() {
+		// all this is only to get the application args		
+		EnvironmentInfo envInfo = null;
+		ServiceReference envInfoSR = context.getServiceReference(EnvironmentInfo.class.getName());
+		if (envInfoSR != null)
+			envInfo = (EnvironmentInfo) context.getService(envInfoSR);
+		if (envInfo == null)
+			throw new IllegalStateException();
+		this.allArgs = envInfo.getAllArgs();
+		// we have what we want - release the service
+		context.ungetService(envInfoSR);
+	}
+
+	public void stop(BundleContext ctx) throws Exception {
+		releasePlatform();
+		configurationFactorySR.unregister();
+	}
+
+	private void releasePlatform() {
+		if (platformTracker == null)
+			return;
+		platformTracker.close();
+		platformTracker = null;
+	}
+	private IPlatform acquirePlatform() {
+		if (platformTracker == null) {
+			platformTracker = new ServiceTracker(context, IPlatform.class.getName(), null);
+			platformTracker.open();
+		}
+		IPlatform result = (IPlatform) platformTracker.getService();
+		while (result == null) {
+			try {
+				platformTracker.waitForService(1000);
+				result = (IPlatform) platformTracker.getService();
+			} catch (InterruptedException ie) {
+			}
+		}
+		return result;
+	}
+
+	private void installBundles() {
+		String metaPath = platform.getLocation().append(".metadata").toOSString();
+		URL installURL = platform.getInstallURL();
+		ServiceReference reference = context.getServiceReference(StartLevel.class.getName());
+		StartLevel start = null;
+		if (reference != null)
+			start = (StartLevel) context.getService(reference);
+		try {
+			URL[] plugins = configuration.getPluginPath();
+			ArrayList installed = new ArrayList(plugins.length);
+			for (int i = 0; i < plugins.length; i++) {
+				String location = plugins[i].toExternalForm();
+				try {
+					checkOrGenerateManifest(location);
+					location = "reference:" + location.substring(0, location.lastIndexOf('/'));
+					if (!isInstalled(location)) {
+						Bundle target = context.installBundle(location);
+						installed.add(target);
+						if (start != null)
+							start.setBundleStartLevel(target, 4);
+					}
+				} catch (Exception e) {
+					System.err.println("Ignoring bundle at: " + location);
+					System.err.println(e.getMessage());
+				}
+			}
+			context.ungetService(reference);
+			refreshPackages((Bundle[]) installed.toArray(new Bundle[installed.size()]));
+			if (System.getProperty("eclipse.application") == null || System.getProperty("eclipse.application").equals(PlatformConfiguration.RECONCILER_APP))
+				System.setProperty("eclipse.application", configuration.getApplicationIdentifier());
+			//			if (config.getApplicationIdentifier().equals(PlatformConfiguration.RECONCILER_APP) ) {
+			//				reconcilerListener = reconcilerListener();
+			//				context.addBundleListener(reconcilerListener);
+			//			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} finally {
+			releasePlatform();
+		}
+	}
+
+	private BundleListener reconcilerListener() {
+		return new BundleListener() {
+			public void bundleChanged(BundleEvent event) {
+				String buid = event.getBundle().getGlobalName();
+				if (event.getType() == BundleEvent.STOPPED && buid != null && buid.equals("org.eclipse.update.core"))
+					runPostReconciler();
+			}
+		};
+	}
+
+	private void runPostReconciler() {
+		Runnable postReconciler = new Runnable() {
+			public void run() {
+				try {
+					Bundle apprunner = context.getBundle("org.eclipse.core.applicationrunner");
+					apprunner.stop();
+					context.removeBundleListener(reconcilerListener);
+					try {
+						PlatformConfiguration.shutdown();
+					} catch (IOException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					installBundles();
+					apprunner.start();
+				} catch (BundleException be) {
+					be.printStackTrace();
+				}
+			}
+		};
+		new Thread(postReconciler, "Post reconciler").start();
+	}
+	/**
+	 * @param location
+	 */
+	private void checkOrGenerateManifest(String pluginManifestLocationURL) {
+		if (converter == null)
+			return;
+		String pluginManifestLocation = null;
+		try {
+			pluginManifestLocation = new URL(pluginManifestLocationURL).getPath();
+		} catch (MalformedURLException e) {
+			return;
+		}
+		File pluginDir = new File(pluginManifestLocation).getParentFile();
+		if (shouldIgnore(pluginDir.getName()))
+			return;
+		File manifest = new File(pluginDir, "META-INF/MANIFEST.MF");
+		if (manifest.exists())
+			return;
+		// bail if the install location is not writable and we don't know where else to write to
+		if (cacheLocation == null)
+			return;
+		File generationLocation = new File(cacheLocation, computeFileName(pluginDir.getPath()) + ".MF");
+		if (generationLocation.exists())
+			return;
+		if (!converter.convertManifest(pluginDir, generationLocation))
+			System.out.println(pluginDir + " manifest generation failed");
+	}
+	/*
+	 * Derives a file name corresponding to a path:
+	 * c:\autoexec.bat -> c__autoexec.bat
+	 */
+	private String computeFileName(String filePath) {
+		StringBuffer newName = new StringBuffer(filePath);
+		for (int i = 0; i < filePath.length(); i++) {
+			char c = newName.charAt(i);
+			if (c == ':' || c == '/' || c == '\\')
+				newName.setCharAt(i, '_');
+		}
+		return newName.toString();
+	}
+	/**
+	 * This is a major hack to try to get the reconciler application running. However we should find a way to not run it.
+	 * @param args
+	 * @param metaPath
+	 * @return
+	 */
+	private PlatformConfiguration getPlatformConfiguration(String[] args, String metaPath, URL installURL) {
+		try {
+			PlatformConfiguration.startup(args, null, null, metaPath, installURL);
+		} catch (Exception e) {
+			if (platformTracker != null) {
+				String message = e.getMessage();
+				if (message == null)
+					message = "";
+				IStatus status = new Status(IStatus.ERROR, IPlatform.PI_RUNTIME, IStatus.OK, message, e);
+				((IPlatform) platformTracker.getService()).getLog(context.getBundle()).log(status);
+			}
+		}
+		return PlatformConfiguration.getCurrent();
+
+	}
+
+	/**
+	 * Do PackageAdmin.refreshPackages() in a synchronous way.  After installing
+	 * all the requested bundles we need to do a refresh and want to ensure that 
+	 * everything is done before returning.
+	 * @param bundles
+	 */
+	private void refreshPackages(Bundle[] bundles) {
+		if (bundles.length == 0)
+			return;
+		ServiceReference packageAdminRef = context.getServiceReference(PackageAdmin.class.getName());
+		PackageAdmin packageAdmin = null;
+		if (packageAdminRef != null) {
+			packageAdmin = (PackageAdmin) context.getService(packageAdminRef);
+			if (packageAdmin == null)
+				return;
+		}
+		// TODO this is such a hack it is silly.  There are still cases for race conditions etc
+		// but this should allow for some progress...
+		final Object semaphore = new Object();
+		FrameworkListener listener = new FrameworkListener() {
+			public void frameworkEvent(FrameworkEvent event) {
+				if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED)
+					synchronized (semaphore) {
+						semaphore.notifyAll();
+					}
+			}
+		};
+		context.addFrameworkListener(listener);
+		packageAdmin.refreshPackages(bundles);
+		synchronized (semaphore) {
+			try {
+				semaphore.wait();
+			} catch (InterruptedException e) {
+			}
+		}
+		context.removeFrameworkListener(listener);
+		context.ungetService(packageAdminRef);
+	}
+
+	private boolean isInstalled(String location) {
+		Bundle[] installed = context.getBundles();
+		for (int i = 0; i < installed.length; i++) {
+			Bundle bundle = installed[i];
+			if (location.equalsIgnoreCase(bundle.getLocation()))
+				return true;
+		}
+		return false;
+	}
+
+	private void loadOptions() {
+		// all this is only to get the application args		
+		DebugOptions service = null;
+		ServiceReference reference = context.getServiceReference(DebugOptions.class.getName());
+		if (reference != null)
+			service = (DebugOptions) context.getService(reference);
+		if (service == null)
+			return;
+		try {
+			DEBUG = service.getBooleanOption(OPTION_DEBUG, false);
+			if (!DEBUG)
+				return;
+			DEBUG_CONVERTER = service.getBooleanOption(OPTION_DEBUG_CONVERTER, false);
+		} finally {
+			// we have what we want - release the service
+			context.ungetService(reference);
+		}
+	}
+	public static BundleContext getBundleContext() {
+		return context;
+	}
+}
\ No newline at end of file
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java
new file mode 100644
index 0000000..2c31cbe
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfiguration.java
@@ -0,0 +1,566 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * Platform configuration interface. Represents the runtime
+ * configuration used by the Eclipse platform. Any configuration
+ * changes do not take effect until next startup of the Eclipse
+ * platform
+ * 
+ * @since 2.0
+ */
+public interface IPlatformConfiguration {
+
+	/**
+	 * Configuration entry representing an install site.
+	 * 
+	 * @since 2.0 
+	 */
+	public interface ISiteEntry {
+
+		/**
+		 * Returns the URL for this site
+		 * 
+		 * @return site url
+		 * @since 2.0
+		 */
+		public URL getURL();
+
+		/**
+		 * Returns the policy for this site
+		 * 
+		 * @return site policy
+		 * @since 2.0
+		 */
+		public ISitePolicy getSitePolicy();
+
+		/**
+		 * Sets the site policy
+		 * 
+		 * @param policy site policy
+		 * @since 2.0
+		 */
+		public void setSitePolicy(ISitePolicy policy);
+
+		/**
+		 * Returns a list of features visible on the site. Note, that this is simply a 
+		 * reflection of the site content. The features may or may not be actually configured.
+		 * 
+		 * @return an array of feature entries, or an empty array if no features are found.
+		 * A feature entry is returned as a path relative to the site URL
+		 * @since 2.0
+		 */
+		public String[] getFeatures();
+
+		/**
+		 * Returns a list of plug-ins visible on the site. Note, that this is simply a 
+		 * reflection of the site content and the current policy for the site. The plug-ins
+		 * may or may not end up being used by Eclipse (depends on which plug-in are 
+		 * actually bound by the platform).
+		 * 
+		 * @return an array of plug-in entries, or an empty array if no plug-ins are found.
+		 * A plug-in entry is returned as a path relative to the site URL		 * 
+		 * @since 2.0
+		 */
+		public String[] getPlugins();
+
+		/**
+		 * Returns a stamp reflecting the current state of the site. If called repeatedly,
+		 * returns the same value as long as no changes were made to the site (changes to
+		 * features or plugins).
+		 * 
+		 * @return site change stamp
+		 * @since 2.0
+		 */
+		public long getChangeStamp();
+
+		/**
+		 * Returns a stamp reflecting the current state of the features on the site. 
+		 * If called repeatedly, returns the same value as long as no changes were made to
+		 * features on the site.
+		 * 
+		 * @return site features change stamp 
+		 * @since 2.0
+		 */
+		public long getFeaturesChangeStamp();
+
+		/**
+		 * Returns a stamp reflecting the current state of the plug-ins on the site. 
+		 * If called repeatedly, returns the same value as long as no changes were made to
+		 * plug-ins on the site.
+		 * 
+		 * @return site plug-ins change stamp 
+		 * @since 2.0
+		 */
+		public long getPluginsChangeStamp();
+
+		/**
+		 * Returns an indication whether the site can be updated.
+		 * 
+		 * @return <code>true</code> if site can be updated, <code>false</code> otherwise
+		 * @since 2.0
+		 */
+		public boolean isUpdateable();
+
+		/**
+		 * Returns an indication whether the site represents an install site
+		 * that has been linked via a native installer (using the links/<linkfile>
+		 * mechanism)
+		 * 
+		 * @return <code>true</code> if the site is linked, <code>false</code> otherwise
+		 * @since 2.0
+		 */
+		public boolean isNativelyLinked();
+	}
+
+	/**
+	 * Site policy. The site policy object determines how plug-ins
+	 * contained on the site are processed during startup. In general,
+	 * there are 3 ways of configuring a site policy
+	 * <ul>
+	 * <li>explicitly specify which plug-ins are to be included at
+	 * startup (type==USER_INCLUDE). Any other plug-ins located
+	 * at the site are ignored at startup. This is typically the best
+	 * policy when using remote sites where the user wishes
+	 * to retain explicit control over the plug-ins that are included
+	 * from such site.
+	 * <li>explicitly specify which plug-ins are to be excluded at
+	 * startup (type==USER-EXCLUDE). All other plug-ins located
+	 * at the site are used at startup. This policy requires that
+	 * the site support an access "protocol" that allows plug-in
+	 * discovery. In general, these are sites defined using the "file"
+	 * URL protocol. This is typically the best policy for local
+	 * install sites (on the user system).
+	 * </ul>
+	 * 
+	 * @since 2.0
+	 */
+	public interface ISitePolicy {
+
+		/**
+		 * Policy type constants.
+		 */
+
+		/** 
+		 * User-defined inclusion list. The list associated with this
+		 * policy type is interpreted as path entries to included plugin.xml
+		 * or fragment.xml <b>relative</b> to the site URL
+		 */
+		public static final int USER_INCLUDE = 0;
+
+		/**
+		 * User-defined exclusion list. The list associated with this
+		 * policy type is interpreted as path entries to excluded plugin.xml
+		 * or fragment.xml <b>relative</b> to the site URL
+		 */
+		public static final int USER_EXCLUDE = 1;
+
+		/**
+		 * Return policy type
+		 * 
+		 * @return policy type
+		 * @since 2.0
+		 */
+		public int getType();
+
+		/**
+		 * Return policy inclusion/ exclusion list
+		 * 
+		 * @return the list as an array
+		 * @since 2.0
+		 */
+		public String[] getList();
+
+		/**
+		 * Set new policy list. The list entries are interpreted based on the policy
+		 * type. See description of the policy type constants for details.
+		 * 
+		 * @param list policy inclusion/ exclusion list as an array.
+		 * Returns an empty array if there are no entries.
+		 * @see #USER_INCLUDE
+		 * @see #USER_EXCLUDE
+		 * @since 2.0
+		 */
+		public void setList(String[] list);
+	}
+
+	/**
+	 * Feature entry.
+	 * Represents runtime "hints" about configured features.
+	 * The information is used during execution to locate the
+	 * correct attribution information for a feature. Note,
+	 * that a typical configuration can declare multiple feature
+	 * entries. At execution time, only one can be selected as
+	 * the active primary feature. This is determined based on 
+	 * specified command line arguments or computed defaults.
+	 * 
+	 * @since 2.0
+	 */
+	public interface IFeatureEntry {
+
+		/**
+		 * Returns feature identifier.
+		 * @return feature identifier
+		 * @since 2.0
+		 */
+		public String getFeatureIdentifier();
+
+		/**
+		 * Returns the currently configured version for the feature.
+		 * @return feature version (as string), or <code>null</code>
+		 * @since 2.0
+		 */
+		public String getFeatureVersion();
+
+		/**
+		 * Returns the identifier of the feature plug-in for this feature entry.
+			 *  Note,      that there is no guarantee that a feature in fact
+			 * supplies a corresponding feature plugin, so the result can be
+			 * <code>null</code>. Also, if supplied, there is no guarantee that the
+			 * plugin will in fact be loaded into the plug-in registry at runtime
+			 * (due to rules and constraint checking performed by the registry
+			 * loading support). Consequently code making use of this method must
+			 * handle these conditions.
+		 * @return feature identifier (as string), or <code>null</code>
+		 * @since 2.1
+		 */
+		public String getFeaturePluginIdentifier();
+
+		/**
+		 * Returns the version of the feature plug-in for this feature
+		 * entry. Note, that there is no guarantee that a feature in fact
+		 * supplies a corresponding feature plugin, so the result can be
+		 * <code>null</code>. Also, if supplied, there is no guarantee that the
+		 * plugin will in fact be loaded into the plug-in registry at runtime
+		 * (due to rules and constraint checking performed by the registry
+		 * loading support). Consequently code making use of this method must
+		 * handle these conditions.
+		 * @return feature version (as string), or <code>null</code>
+		 * @since 2.0
+		 */
+		public String getFeaturePluginVersion();
+
+		/**
+		 * Returns the application to run when this feature is the
+		 * primary feature.
+		 * @return application identifier, or <code>null</code> 
+		 * @since 2.0
+		 */
+		public String getFeatureApplication();
+
+		/**
+		 * Returns URLs to the feature "root" locations. The root
+		 * URLs are install locations of the feature plugin and its
+		 * fragments.
+		 *
+		 * @return array of URLs, or an empty array
+		 * @since 2.0
+		 */
+		public URL[] getFeatureRootURLs();
+
+		/**
+		 * Returns an indication whether this feature has been defined
+		 * to act as a primary feature.
+		 * @return <code>true</code> if the feature can be primary,
+		 * <code>false</code> otherwise.
+		 * @since 2.0
+		 */
+		public boolean canBePrimary();
+	}
+
+	/**
+	 * Create a site entry
+	 *
+	 * @param url site URL
+	 * @param policy site policy
+	 * @return created site entry
+	 * @since 2.0
+	 */
+	public ISiteEntry createSiteEntry(URL url, ISitePolicy policy);
+
+	/**
+	 * Create a site policy. The policy determines the way the site
+	 * plug-in are processed at startpu
+	 *
+	 * @param type policy type
+	 * @param list an array of site-relative paths representing the
+	 * inclusion/ exclusion list
+	 * @return created site policy entry
+	 * @since 2.0
+	 */
+	public ISitePolicy createSitePolicy(int type, String[] list);
+
+	/**
+	 * Create a feature entry
+	 * @param id feature identifier. Must not be <code>null</code>.
+	 * @param version feature version (as String). Can be <code>null</code>.
+	 * @param pluginVersion version of the feature plugin (as String). Can be
+	 * <code>null</code>.
+	 * @param primary <code>true</code> if the feature is defined as a primary
+	 * feature, otherwise <code>false</code>.
+	 * @param application identifier of the application to run when 
+	 * this feature is the primary feature. Can be <code>null</code>.
+	 * If specified, the identifier must represent a valid extension 
+	 * registered in the <code>org.eclipse.core.runtime.applications</code>
+	 * extension point.
+	 * @param an array of URLs to feature root directories.
+	 * These are URLs to install locations for the feature plugin
+	 * and its fragments. Can be <code>null</code>.
+	 * @return create feature entry
+	 * @since 2.0
+	 */
+	public IFeatureEntry createFeatureEntry(String id, String version, String pluginVersion, boolean primary, String application, URL[] root);
+
+	/**
+	 * Create a feature entry
+	 * @param id feature identifier. Must not be <code>null</code>.
+	 * @param version feature version (as String). Can be <code>null</code>.
+	 * @param pluginIdentifier identifier of the feature plugin (as String). Can
+	 * be <code>null</code>.
+	 * @param  pluginVersion  version of the feature plugin (as String). Can be
+	 * <code>null</code>.
+	 * @param primary <code>true</code> if the feature is defined as a primary
+	 * feature, otherwise <code>false</code>.
+	 * @param application identifier of the application to run when
+	 * this feature is the primary feature. Can be <code>null</code>.
+	 * If specified, the identifier must represent a valid extension
+	 * registered in the <code>org.eclipse.core.runtime.applications</code>
+	 * extension point.
+	 * @param an array of URLs to feature root directories.
+	 * These are URLs to install locations for the feature plugin
+	 * and its fragments. Can be <code>null</code>.
+	 * @return create feature entry
+	 * @since 2.1
+	 */
+	public IFeatureEntry createFeatureEntry(String id, String version, String pluginIdentifier, String pluginVersion, boolean primary, String application, URL[] root);
+
+	/**
+	 * Configures the specified site entry. If a site entry with the
+	 * same site URL is already configured, the entry is <b>not</b> replaced.
+	 * 
+	 * @param entry site entry 
+	 * @since 2.0
+	 */
+	public void configureSite(ISiteEntry entry);
+
+	/**
+	 * Configures the specified site entry. If a site entry with the
+	 * same site URL is already configured, the replacement behavior for
+	 * the entry can be specified.
+	 * 
+	 * @param entry site entry 
+	 * @param  flag indicating whether an existing configured entry with
+	 * the same URL should be replaced (<code>true</code>) or not (<code>false</code>).
+	 * @since 2.0
+	 */
+	public void configureSite(ISiteEntry entry, boolean replace);
+
+	/**
+	 * Unconfigures the specified entry. Does not do anything if the entry
+	 * is not configured.
+	 * 
+	 * @param entry site entry
+	 * @since 2.0
+	 */
+	public void unconfigureSite(ISiteEntry entry);
+
+	/**
+	 * Returns configured site entries
+	 * 
+	 * @return array of site entries. Returns an empty array if no sites are
+	 * configured
+	 * @since 2.0
+	 */
+	public ISiteEntry[] getConfiguredSites();
+
+	/**
+	 * Returns a site entry matching the specified URL
+	 * 
+	 * @param url site url
+	 * @return matching site entry, or <code>null</code> if no match found
+	 * @since 2.0
+	 */
+	public ISiteEntry findConfiguredSite(URL url);
+
+	/**
+	 * Configures the feature entry.
+	 * If another feature entry with the same feature identifier 
+	 * already exists, it is replaced.
+	 * @param entry feature entry
+	 * @since 2.0
+	 */
+	public void configureFeatureEntry(IFeatureEntry entry);
+
+	/**
+	 * Unconfigures the specified feature entry if it exists.
+	 * @param entry feature entry
+	 * @since 2.0
+	 */
+	public void unconfigureFeatureEntry(IFeatureEntry entry);
+
+	/**
+	 * Returns a list of configured feature entries.
+	 * @return array or entries, or an empty array if no entries
+	 * are configured
+	 * @since 2.0
+	 */
+	public IFeatureEntry[] getConfiguredFeatureEntries();
+
+	/**
+	 * Locates the specified feature entry.
+	 * @param id feature identifier
+	 * @return ferature entry, or <code>null</code>.
+	 * @since 2.0
+	 */
+	public IFeatureEntry findConfiguredFeatureEntry(String id);
+
+	/**
+	 * Returns the URL location of the configuration information
+	 * 
+	 * @return configuration location URL, or <code>null</code> if the
+	 * configuration location could not be determined.
+	 * @since 2.0
+	 */
+	public URL getConfigurationLocation();
+
+	/**
+	 * Returns a stamp reflecting the current state of the configuration. If called repeatedly,
+	 * returns the same value as long as no changes were made to the configuration (changes to
+	 * sites, features or plugins).
+	 * 
+	 * @return configuration change stamp
+	 * @since 2.0
+	 */
+	public long getChangeStamp();
+
+	/**
+	 * Returns a stamp reflecting the current state of the features in the configuration. 
+	 * If called repeatedly, returns the same value as long as no changes were made to
+	 * features in the configuration.
+	 * 
+	 * @return configuration features change stamp 
+	 * @since 2.0
+	 */
+	public long getFeaturesChangeStamp();
+
+	/**
+	 * Returns a stamp reflecting the current state of the plug-ins in the configuration. 
+	 * If called repeatedly, returns the same value as long as no changes were made to
+	 * plug-ins in the configuration.
+	 * 
+	 * @return configuration plug-ins change stamp 
+	 * @since 2.0
+	 */
+	public long getPluginsChangeStamp();
+
+	/**
+	 * Returns the identifier of the configured primary feature. A primary feature
+	 * is used to specify product customization information for a running instance
+	 * of Eclipse. 
+	 * 
+	 * @return primary feature identifier, or <code>null</code> if none configured
+	 * @since 2.0
+	 */
+	public String getPrimaryFeatureIdentifier();
+
+	/**
+	 * Computes the plug-in path for this configuration. The result includes all plug-ins
+	 * visible on each of the configured sites based on each site policy.
+	 * 
+	 * @return an array of plug-in path elements (full URL entries), or an empty array.
+	 * @since 2.0
+	 */
+	public URL[] getPluginPath();
+
+	/**
+	 * Returns an array of bootstrap plugin identifiers whose
+	 * location needs to be explicitly identified in the configuration.
+	 * 
+	 * @return an array of identifiers, or empty array
+	 * otherwise
+	 * @since 2.0
+	 */
+	public String[] getBootstrapPluginIdentifiers();
+
+	/**
+	 * Sets the location of a bootstrap plugin.
+	 * 
+	 * @see IPlatformConfiguration#getBootstrapPluginIdentifiers()
+	 * @param id plugin identifier. Must match one of the entries returned
+	 * by getBootstrapPluginIdentifiers()
+	 * @param location
+	 * @since 2.0
+	 */
+	public void setBootstrapPluginLocation(String id, URL location);
+
+	/**
+	 * Returns an indication whether the configuration can be updated.
+	 * 
+	 * @return <code>true</code> if configuration can be updated, <code>false</code> 
+	 * otherwise
+	 * @since 2.0
+	 */
+	public boolean isUpdateable();
+
+	/**
+	 * Returns an indication whether the configuration is transient. A transient
+	 * configuration typically represents a scenario where the configuration
+	 * was computed for a single instantiation of the platform and is not
+	 * guaranteed to be valid on subsequent instantiations.
+	 * 
+	 * @return <code>true</code> if configuration is transient, <code>false</code> 
+	 * otherwise
+	 * @since 2.0
+	 */
+	public boolean isTransient();
+
+	/**
+	 * Indicates whether the configuration is transient or not. A transient
+	 * configuration typically represents a scenario where the configuration
+	 * was computed for a single instantiation of the platform and is not
+	 * guaranteed to be valid on subsequent instantiations. This method has
+	 * no effect if called on the current platform configuration.
+	 * 
+	 * @see BootLoader#getCurrentPlatformConfiguration()
+	 * @param value <code>true</code> if configuration is transient, <code>false</code> 
+	 * otherwise
+	 * @since 2.0
+	 */
+	public void isTransient(boolean value);
+
+	/**
+	 * Called to refresh the configuration information. In particular,
+	 * causes change stamps to be recomputed based on the current
+	 * configuration state, and updates the lists of available plug-ins.
+	 * @since 2.0
+	 */
+	public void refresh();
+
+	/**
+	 * Called to save the configuration information
+	 * @since 2.0
+	 */
+	public void save() throws IOException;
+
+	/**
+	 * Called to save the configuration information in the
+	 * specified location
+	 * 
+	 * @param url save location.
+	 * @since 2.0
+	 */
+	public void save(URL url) throws IOException;
+
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java
new file mode 100644
index 0000000..3fcdebf
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPlatformConfigurationFactory.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+public interface IPlatformConfigurationFactory {
+	/**
+	 * Returns the current platform configuration.
+	 * 
+	 * @return platform configuration used in current instance of platform
+	 */	
+	public IPlatformConfiguration getCurrentPlatformConfiguration();
+	/**
+	 * Returns a platform configuration object, optionally initialized with previously saved
+	 * configuration information.
+	 * 
+	 * @param url location of previously save configuration information. If <code>null</code>
+	 * is specified, an empty configuration object is returned
+	 * @return platform configuration used in current instance of platform
+	 */	
+	public IPlatformConfiguration getPlatformConfiguration(URL url) throws IOException;
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPluginConverter.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPluginConverter.java
new file mode 100644
index 0000000..5652156
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/IPluginConverter.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.io.File;
+
+public interface IPluginConverter {
+	/**
+	 * Converts a plug-in/fragment into a bundle (host/fragment).
+	 * @param pluginLocation
+	 * @param bundleManifestLocation
+	 * @return <code>true</coed>
+	 */
+	public boolean convertManifest(File pluginLocation, File bundleManifestLocation);
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/PlatformConfiguration.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/PlatformConfiguration.java
new file mode 100644
index 0000000..534c583
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/PlatformConfiguration.java
@@ -0,0 +1,2929 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import org.eclipse.core.internal.boot.PlatformURLConnection;
+import org.eclipse.core.internal.boot.PlatformURLHandler;
+
+public class PlatformConfiguration implements IPlatformConfiguration {
+
+	private static PlatformConfiguration currentPlatformConfiguration = null;
+
+	private URL configLocation;
+	private URL rootLocation;
+	private HashMap sites;
+	private HashMap externalLinkSites; // used to restore prior link site state
+	private HashMap cfgdFeatures;
+	private HashMap bootPlugins;
+	private String defaultFeature;
+	private long lastChangeStamp;
+	private long changeStamp;
+	private boolean changeStampIsValid = false;
+	private long lastFeaturesChangeStamp;
+	private long featuresChangeStamp;
+	private boolean featuresChangeStampIsValid = false;
+	private long lastPluginsChangeStamp;
+	private long pluginsChangeStamp;
+	private boolean pluginsChangeStampIsValid = false;
+	private boolean featureChangesConfigured = false;
+	private boolean transientConfig = false;
+	private File cfgLockFile;
+	private RandomAccessFile cfgLockFileRAF;
+	private BootDescriptor runtimeDescriptor;
+
+	private static String cmdConfiguration = null;
+	private static String cmdFeature = null;
+	private static String cmdApplication = null;
+	private static URL cmdPlugins = null;
+	private static boolean cmdInitialize = false;
+	private static boolean cmdFirstUse = false;
+	private static boolean cmdUpdate = false;
+	private static boolean cmdNoUpdate = false;
+	private static boolean cmdDev = false;
+
+	static boolean DEBUG = false;
+
+	private static final String BOOT_XML = "boot.xml"; //$NON-NLS-1$
+	private static final String BOOT_PLUGIN_ID = "org.eclipse.core.boot"; //$NON-NLS-1$
+	private static final String RUNTIME_PLUGIN_ID = "org.eclipse.core.runtime"; //$NON-NLS-1$
+
+	private static final String ECLIPSE = "eclipse"; //$NON-NLS-1$
+	private static final String PLUGINS = "plugins"; //$NON-NLS-1$
+	private static final String FEATURES = "features"; //$NON-NLS-1$
+	private static final String CONFIG_DIR = ".config"; //$NON-NLS-1$
+	private static final String CONFIG_FILE = CONFIG_DIR + "/platform.cfg"; //$NON-NLS-1$
+	private static final String CONFIG_FILE_INIT = "install.ini"; //$NON-NLS-1$
+	private static final String CONFIG_FILE_LOCK_SUFFIX = ".lock"; //$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 CHANGES_MARKER = ".newupdates"; //$NON-NLS-1$
+	private static final String LINKS = "links"; //$NON-NLS-1$
+	private static final String PLUGIN_XML = "plugin.xml"; //$NON-NLS-1$
+	private static final String FRAGMENT_XML = "fragment.xml"; //$NON-NLS-1$
+	private static final String FEATURE_XML = "feature.xml"; //$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$
+
+	private static final String[] BOOTSTRAP_PLUGINS = { "org.eclipse.core.boot" }; //$NON-NLS-1$
+	private static final String CFG_BOOT_PLUGIN = "bootstrap"; //$NON-NLS-1$
+	private static final String CFG_SITE = "site"; //$NON-NLS-1$
+	private static final String CFG_URL = "url"; //$NON-NLS-1$
+	private static final String CFG_POLICY = "policy"; //$NON-NLS-1$
+	private static final String[] CFG_POLICY_TYPE = { "USER-INCLUDE", "USER-EXCLUDE" }; //$NON-NLS-1$ //$NON-NLS-2$
+	private static final String CFG_POLICY_TYPE_UNKNOWN = "UNKNOWN"; //$NON-NLS-1$
+	private static final String CFG_LIST = "list"; //$NON-NLS-1$
+	private static final String CFG_STAMP = "stamp"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_STAMP = "stamp.features"; //$NON-NLS-1$
+	private static final String CFG_PLUGIN_STAMP = "stamp.plugins"; //$NON-NLS-1$
+	private static final String CFG_UPDATEABLE = "updateable"; //$NON-NLS-1$
+	private static final String CFG_LINK_FILE = "linkfile"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY = "feature"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_DEFAULT = "feature.default.id"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_ID = "id"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_PRIMARY = "primary"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_VERSION = "version"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_PLUGIN_VERSION = "plugin-version"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_PLUGIN_IDENTIFIER = "plugin-identifier"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_APPLICATION = "application"; //$NON-NLS-1$
+	private static final String CFG_FEATURE_ENTRY_ROOT = "root"; //$NON-NLS-1$
+
+	private static final String INIT_DEFAULT_FEATURE_ID = "feature.default.id"; //$NON-NLS-1$
+	private static final String INIT_DEFAULT_PLUGIN_ID = "feature.default.plugin.id"; //$NON-NLS-1$
+	private static final String INIT_DEFAULT_FEATURE_APPLICATION = "feature.default.application"; //$NON-NLS-1$
+	private static final String DEFAULT_FEATURE_ID = "org.eclipse.platform"; //$NON-NLS-1$
+	private static final String DEFAULT_FEATURE_APPLICATION = "org.eclipse.ui.workbench"; //$NON-NLS-1$
+
+	private static final String CFG_VERSION = "version"; //$NON-NLS-1$
+	private static final String CFG_TRANSIENT = "transient"; //$NON-NLS-1$
+	private static final String VERSION = "2.1"; //$NON-NLS-1$
+	private static final String EOF = "eof"; //$NON-NLS-1$
+	private static final int CFG_LIST_LENGTH = 10;
+
+	private static final int DEFAULT_POLICY_TYPE = ISitePolicy.USER_EXCLUDE;
+	private static final String[] DEFAULT_POLICY_LIST = new String[0];
+
+	private static final String LINK_PATH = "path"; //$NON-NLS-1$
+	private static final String LINK_READ = "r"; //$NON-NLS-1$
+	private static final String LINK_READ_WRITE = "rw"; //$NON-NLS-1$
+
+	private static final String CMD_CONFIGURATION = "-configuration"; //$NON-NLS-1$
+	private static final String CMD_FEATURE = "-feature"; //$NON-NLS-1$
+	private static final String CMD_APPLICATION = "-application"; //$NON-NLS-1$
+	private static final String CMD_PLUGINS = "-plugins"; //$NON-NLS-1$
+	private static final String CMD_UPDATE = "-update"; //$NON-NLS-1$
+	private static final String CMD_INITIALIZE = "-initialize"; //$NON-NLS-1$
+	private static final String CMD_FIRSTUSE = "-firstuse"; //$NON-NLS-1$
+	private static final String CMD_NO_UPDATE = "-noupdate"; //$NON-NLS-1$
+	private static final String CMD_NEW_UPDATES = "-newUpdates"; //$NON-NLS-1$
+	private static final String CMD_DEV = "-dev"; // triggers -noupdate //$NON-NLS-1$
+
+	protected static final String RECONCILER_APP = "org.eclipse.update.core.reconciler"; //$NON-NLS-1$
+
+	private static final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+	private static URL installURL;
+
+	public class SiteEntry implements IPlatformConfiguration.ISiteEntry {
+
+		private URL url; // this is the external URL for the site
+		private URL resolvedURL; // this is the resolved URL used internally
+		private ISitePolicy policy;
+		private boolean updateable = true;
+		private ArrayList features;
+		private ArrayList plugins;
+		private PlatformConfiguration parent;
+		private long lastChangeStamp;
+		private long changeStamp;
+		private boolean changeStampIsValid = false;
+		private long lastFeaturesChangeStamp;
+		private long featuresChangeStamp;
+		private boolean featuresChangeStampIsValid = false;
+		private long lastPluginsChangeStamp;
+		private long pluginsChangeStamp;
+		private boolean pluginsChangeStampIsValid = false;
+		private String linkFileName = null;
+
+		private SiteEntry() {
+		}
+		private SiteEntry(URL url, ISitePolicy policy, PlatformConfiguration parent) {
+			if (url == null)
+				throw new IllegalArgumentException();
+
+			if (policy == null)
+				throw new IllegalArgumentException();
+
+			if (parent == null)
+				throw new IllegalArgumentException();
+
+			this.url = url;
+			this.policy = policy;
+			this.parent = parent;
+			this.features = null;
+			this.plugins = null;
+			this.resolvedURL = this.url;
+			if (url.getProtocol().equals(PlatformURLHandler.PROTOCOL)) {
+				try {
+					resolvedURL = resolvePlatformURL(url); // 19536
+				} catch (IOException e) {
+					// will use the baseline URL ...
+				}
+			}
+		}
+
+		/*
+		 * @see ISiteEntry#getURL()
+		 */
+		public URL getURL() {
+			return url;
+		}
+
+		/*
+		* @see ISiteEntry#getSitePolicy()
+		*/
+		public ISitePolicy getSitePolicy() {
+			return policy;
+		}
+
+		/*
+		 * @see ISiteEntry#setSitePolicy(ISitePolicy)
+		 */
+		public synchronized void setSitePolicy(ISitePolicy policy) {
+			if (policy == null)
+				throw new IllegalArgumentException();
+			this.policy = policy;
+		}
+
+		/*
+		 * @see ISiteEntry#getFeatures()
+		 */
+		public String[] getFeatures() {
+			return getDetectedFeatures();
+		}
+
+		/*
+		 * @see ISiteEntry#getPlugins()
+		 */
+		public String[] getPlugins() {
+
+			ISitePolicy policy = getSitePolicy();
+
+			if (policy.getType() == ISitePolicy.USER_INCLUDE)
+				return policy.getList();
+
+			if (policy.getType() == ISitePolicy.USER_EXCLUDE) {
+				ArrayList detectedPlugins = new ArrayList(Arrays.asList(getDetectedPlugins()));
+				String[] excludedPlugins = policy.getList();
+				for (int i = 0; i < excludedPlugins.length; i++) {
+					if (detectedPlugins.contains(excludedPlugins[i]))
+						detectedPlugins.remove(excludedPlugins[i]);
+				}
+				return (String[]) detectedPlugins.toArray(new String[0]);
+			}
+
+			// bad policy type
+			return new String[0];
+		}
+
+		/*
+		 * @see ISiteEntry#getChangeStamp()
+		 */
+		public long getChangeStamp() {
+			if (!changeStampIsValid)
+				computeChangeStamp();
+			return changeStamp;
+		}
+
+		/*
+		 * @see ISiteEntry#getFeaturesChangeStamp()
+		 */
+		public long getFeaturesChangeStamp() {
+			if (!featuresChangeStampIsValid)
+				computeFeaturesChangeStamp();
+			return featuresChangeStamp;
+		}
+
+		/*
+		 * @see ISiteEntry#getPluginsChangeStamp()
+		 */
+		public long getPluginsChangeStamp() {
+			if (!pluginsChangeStampIsValid)
+				computePluginsChangeStamp();
+			return pluginsChangeStamp;
+		}
+
+		/*
+		 * @see ISiteEntry#isUpdateable()
+		 */
+		public boolean isUpdateable() {
+			return updateable;
+		}
+
+		/*
+		 * @see ISiteEntry#isNativelyLinked()
+		 */
+		public boolean isNativelyLinked() {
+			return isExternallyLinkedSite();
+		}
+
+		private String[] detectFeatures() {
+
+			// invalidate stamps ... we are doing discovery
+			changeStampIsValid = false;
+			featuresChangeStampIsValid = false;
+			parent.changeStampIsValid = false;
+			parent.featuresChangeStampIsValid = false;
+
+			features = new ArrayList();
+
+			if (!supportsDetection(resolvedURL))
+				return new String[0];
+
+			// locate feature entries on site
+			File siteRoot = new File(resolvedURL.getFile().replace('/', File.separatorChar));
+			File root = new File(siteRoot, FEATURES);
+
+			String[] list = root.list();
+			String path;
+			File plugin;
+			for (int i = 0; list != null && i < list.length; i++) {
+				path = list[i] + File.separator + FEATURE_XML;
+				plugin = new File(root, path);
+				if (!plugin.exists()) {
+					continue;
+				}
+				features.add(FEATURES + "/" + path.replace(File.separatorChar, '/')); //$NON-NLS-1$
+			}
+			if (DEBUG) {
+				debug(resolvedURL.toString() + " located  " + features.size() + " feature(s)"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			return (String[]) features.toArray(new String[0]);
+		}
+
+		private String[] detectPlugins() {
+
+			// invalidate stamps ... we are doing discovery
+			changeStampIsValid = false;
+			pluginsChangeStampIsValid = false;
+			parent.changeStampIsValid = false;
+			parent.pluginsChangeStampIsValid = false;
+
+			plugins = new ArrayList();
+
+			if (!supportsDetection(resolvedURL))
+				return new String[0];
+
+			// locate plugin entries on site
+			File root = new File(resolvedURL.getFile().replace('/', File.separatorChar) + PLUGINS);
+			String[] list = root.list();
+			String path;
+			File plugin;
+			for (int i = 0; list != null && i < list.length; i++) {
+				path = list[i] + File.separator + PLUGIN_XML;
+				plugin = new File(root, path);
+				if (!plugin.exists()) {
+					path = list[i] + File.separator + FRAGMENT_XML;
+					plugin = new File(root, path);
+					if (!plugin.exists())
+						continue;
+				}
+				plugins.add(PLUGINS + "/" + path.replace(File.separatorChar, '/')); //$NON-NLS-1$
+			}
+			if (DEBUG) {
+				debug(resolvedURL.toString() + " located  " + plugins.size() + " plugin(s)"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			return (String[]) plugins.toArray(new String[0]);
+		}
+
+		private synchronized String[] getDetectedFeatures() {
+			if (features == null)
+				return detectFeatures();
+			else
+				return (String[]) features.toArray(new String[0]);
+		}
+
+		private synchronized String[] getDetectedPlugins() {
+			if (plugins == null)
+				return detectPlugins();
+			else
+				return (String[]) plugins.toArray(new String[0]);
+		}
+
+		private URL getResolvedURL() {
+			return resolvedURL;
+		}
+
+		private void computeChangeStamp() {
+			computeFeaturesChangeStamp();
+			computePluginsChangeStamp();
+			changeStamp = resolvedURL.hashCode() ^ featuresChangeStamp ^ pluginsChangeStamp;
+			changeStampIsValid = true;
+		}
+
+		private synchronized void computeFeaturesChangeStamp() {
+			if (featuresChangeStampIsValid)
+				return;
+
+			long start = 0;
+			if (DEBUG)
+				start = (new Date()).getTime();
+			String[] features = getFeatures();
+			featuresChangeStamp = computeStamp(features);
+			featuresChangeStampIsValid = true;
+			if (DEBUG) {
+				long end = (new Date()).getTime();
+				debug(resolvedURL.toString() + " feature stamp: " + featuresChangeStamp + ((featuresChangeStamp == lastFeaturesChangeStamp) ? " [no changes]" : " [was " + lastFeaturesChangeStamp + "]") + " in " + (end - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+			}
+		}
+
+		private synchronized void computePluginsChangeStamp() {
+			if (pluginsChangeStampIsValid)
+				return;
+
+			long start = 0;
+			if (DEBUG)
+				start = (new Date()).getTime();
+			String[] plugins = getPlugins();
+			pluginsChangeStamp = computeStamp(plugins);
+			pluginsChangeStampIsValid = true;
+			if (DEBUG) {
+				long end = (new Date()).getTime();
+				debug(resolvedURL.toString() + " plugin stamp: " + pluginsChangeStamp + ((pluginsChangeStamp == lastPluginsChangeStamp) ? " [no changes]" : " [was " + lastPluginsChangeStamp + "]") + " in " + (end - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+			}
+		}
+
+		private long computeStamp(String[] targets) {
+
+			long result = 0;
+			if (!supportsDetection(resolvedURL)) {
+				// NOTE:  this path should not be executed until we support running
+				//        from an arbitrary URL (in particular from http server). For
+				//        now just compute stamp across the list of names. Eventually
+				//        when general URLs are supported we need to do better (factor
+				//        in at least the existence of the target). However, given this
+				//        code executes early on the startup sequence we need to be
+				//        extremely mindful of performance issues.
+				for (int i = 0; i < targets.length; i++)
+					result ^= targets[i].hashCode();
+				if (DEBUG)
+					debug("*WARNING* computing stamp using URL hashcodes only"); //$NON-NLS-1$
+			} else {
+				// compute stamp across local targets
+				String rootPath = resolvedURL.getFile().replace('/', File.separatorChar);
+				if (!rootPath.endsWith(File.separator))
+					rootPath += File.separator;
+				File rootFile = new File(rootPath);
+				if (rootFile.exists()) {
+					File f = null;
+					for (int i = 0; i < targets.length; i++) {
+						f = new File(rootFile, targets[i]);
+						if (f.exists())
+							result ^= f.getAbsolutePath().hashCode() ^ f.lastModified() ^ f.length();
+					}
+				}
+			}
+
+			return result;
+		}
+
+		private boolean isExternallyLinkedSite() {
+			return (linkFileName != null && !linkFileName.trim().equals("")); //$NON-NLS-1$
+		}
+
+		private synchronized void refresh() {
+			// reset computed values. Will be updated on next access.
+			lastChangeStamp = changeStamp;
+			lastFeaturesChangeStamp = featuresChangeStamp;
+			lastPluginsChangeStamp = pluginsChangeStamp;
+			changeStampIsValid = false;
+			featuresChangeStampIsValid = false;
+			pluginsChangeStampIsValid = false;
+			features = null;
+			plugins = null;
+		}
+
+	}
+
+	public class SitePolicy implements IPlatformConfiguration.ISitePolicy {
+
+		private int type;
+		private String[] list;
+
+		private SitePolicy() {
+		}
+		private SitePolicy(int type, String[] list) {
+			if (type != ISitePolicy.USER_INCLUDE && type != ISitePolicy.USER_EXCLUDE)
+				throw new IllegalArgumentException();
+			this.type = type;
+
+			if (list == null)
+				this.list = new String[0];
+			else
+				this.list = list;
+		}
+
+		/*
+		 * @see ISitePolicy#getType()
+		 */
+		public int getType() {
+			return type;
+		}
+
+		/*
+		* @see ISitePolicy#getList()
+		*/
+		public String[] getList() {
+			return list;
+		}
+
+		/*
+		 * @see ISitePolicy#setList(String[])
+		 */
+		public synchronized void setList(String[] list) {
+			if (list == null)
+				this.list = new String[0];
+			else
+				this.list = list;
+		}
+
+	}
+
+	public class FeatureEntry implements IPlatformConfiguration.IFeatureEntry {
+		private String id;
+		private String version;
+		private String pluginVersion;
+		private String application;
+		private URL[] root;
+		private boolean primary;
+		private String pluginIdentifier;
+
+		private FeatureEntry(String id, String version, String pluginIdentifier, String pluginVersion, boolean primary, String application, URL[] root) {
+			if (id == null)
+				throw new IllegalArgumentException();
+			this.id = id;
+			this.version = version;
+			this.pluginVersion = pluginVersion;
+			this.pluginIdentifier = pluginIdentifier;
+			this.primary = primary;
+			this.application = application;
+			this.root = (root == null ? new URL[0] : root);
+		}
+
+		private FeatureEntry(String id, String version, String pluginVersion, boolean primary, String application, URL[] root) {
+			this(id, version, id, pluginVersion, primary, application, root);
+		}
+
+		/*
+		 * @see IFeatureEntry#getFeatureIdentifier()
+		 */
+		public String getFeatureIdentifier() {
+			return id;
+		}
+
+		/*
+		 * @see IFeatureEntry#getFeatureVersion()
+		 */
+		public String getFeatureVersion() {
+			return version;
+		}
+
+		/*
+		 * @see IFeatureEntry#getFeaturePluginVersion()
+		 */
+		public String getFeaturePluginVersion() {
+			return pluginVersion;
+		}
+
+		/*
+		 * @see IFeatureEntry#getFeatureApplication()
+		 */
+		public String getFeatureApplication() {
+			return application;
+		}
+
+		/*
+		 * @see IFeatureEntry#getFeatureRootURLs()
+		 */
+		public URL[] getFeatureRootURLs() {
+			return root;
+		}
+
+		/*
+		 * @see IFeatureEntry#canBePrimary()
+		 */
+		public boolean canBePrimary() {
+			return primary;
+		}
+		/*
+		 * @see IFeatureEntry#getFeaturePluginIdentifier()
+		 */
+		public String getFeaturePluginIdentifier() {
+			return pluginIdentifier;
+		}
+
+	}
+
+	private class VersionedIdentifier {
+		private String identifier = ""; //$NON-NLS-1$
+		private int major = 0;
+		private int minor = 0;
+		private int service = 0;
+		private String qualifier = ""; //$NON-NLS-1$
+
+		private static final String VER_SEPARATOR = "."; //$NON-NLS-1$
+		private static final String ID_SEPARATOR = "_"; //$NON-NLS-1$
+
+		public static final int LESS_THAN = -1;
+		public static final int EQUAL = 0;
+		public static final int EQUIVALENT = 1;
+		public static final int COMPATIBLE = 2;
+		public static final int GREATER_THAN = 3;
+
+		public VersionedIdentifier(String s) {
+			if (s == null || (s = s.trim()).equals("")) //$NON-NLS-1$
+				return;
+
+			int loc = s.lastIndexOf(ID_SEPARATOR);
+			if (loc != -1) {
+				this.identifier = s.substring(0, loc);
+				String version = s.substring(loc + 1);
+				parseVersion(version);
+			} else
+				this.identifier = s;
+		}
+
+		public boolean equalIdentifiers(VersionedIdentifier id) {
+			if (id == null)
+				return identifier == null;
+			else
+				return id.identifier.equals(identifier);
+		}
+
+		public int compareVersion(VersionedIdentifier id) {
+
+			if (id == null) {
+				if (major == 0 && minor == 0 && service == 0)
+					return -1;
+				else
+					return 1;
+			}
+
+			if (major > id.major)
+				return GREATER_THAN;
+			if (major < id.major)
+				return LESS_THAN;
+			if (minor > id.minor)
+				return COMPATIBLE;
+			if (minor < id.minor)
+				return LESS_THAN;
+			if (service > id.service)
+				return EQUIVALENT;
+			if (service < id.service)
+				return LESS_THAN;
+			return compareQualifiers(qualifier, id.qualifier);
+		}
+
+		private int compareQualifiers(String q1, String q2) {
+			int result = q1.compareTo(q2);
+			if (result < 0)
+				return LESS_THAN;
+			else if (result > 0)
+				return EQUIVALENT;
+			else
+				return EQUAL;
+		}
+
+		private void parseVersion(String v) {
+			if (v == null || (v = v.trim()).equals("")) //$NON-NLS-1$
+				return;
+
+			try {
+				StringTokenizer st = new StringTokenizer(v, VER_SEPARATOR);
+				ArrayList elements = new ArrayList(4);
+
+				while (st.hasMoreTokens()) {
+					elements.add(st.nextToken());
+				}
+
+				if (elements.size() >= 1)
+					this.major = (new Integer((String) elements.get(0))).intValue();
+				if (elements.size() >= 2)
+					this.minor = (new Integer((String) elements.get(1))).intValue();
+				if (elements.size() >= 3)
+					this.service = (new Integer((String) elements.get(2))).intValue();
+				if (elements.size() >= 4)
+					this.qualifier = removeWhiteSpace((String) elements.get(3));
+
+			} catch (Exception e) {
+				// use what we got so far ...
+			}
+		}
+
+		private String removeWhiteSpace(String s) {
+			char[] chars = s.trim().toCharArray();
+			boolean whitespace = false;
+			for (int i = 0; i < chars.length; i++) {
+				if (Character.isWhitespace(chars[i])) {
+					chars[i] = '_';
+					whitespace = true;
+				}
+			}
+			return whitespace ? new String(chars) : s;
+		}
+	}
+
+	/*
+	 * Element selector for use with "tiny" parser. Parser callers supply
+	 * concrete selectors
+	 */
+	public interface Selector {
+
+		/*
+		 * Method is called to pre-select a specific xml type. Pre-selected
+		 * elements are then fully parsed and result in calls to full
+		 * select method.
+		 * @return <code>true</code> is the element should be considered,
+		 * <code>false</code> otherwise
+		 */
+		public boolean select(String entry);
+
+		/*
+		 * Method is called with a fully parsed element.
+		 * @return <code>true</code> to select this element and terminate the parse,
+		 * <code>false</code> otherwise
+		 */
+		public boolean select(String element, HashMap attributes);
+	}
+
+	/*
+	 * "Tiny" xml parser. Performs a rudimentary parse of a well-formed xml file.
+	 * Is specifically geared to parsing plugin.xml files of "bootstrap" plug-ins
+	 * during the platform startup sequence before full xml plugin is available.
+	 */
+	public static class Parser {
+
+		private ArrayList elements = new ArrayList();
+
+		/*
+		 * Construct parser for the specified file
+		 */
+		public Parser(File file) {
+			try {
+				load(new FileInputStream(file));
+			} catch (Exception e) {
+				// continue ... actual parsing will report errors
+			}
+		}
+
+		/*
+		 * Construct parser for the specified URL
+		 */
+		public Parser(URL url) {
+			try {
+				load(url.openStream());
+			} catch (Exception e) {
+				// continue ... actual parsing will report errors
+			}
+		}
+
+		/*
+		 * Return selected elements as an (attribute-name, attribute-value) map.
+		 * The name of the selected element is returned as the value of entry with
+		 * name "<element>".
+		 * @return attribute map for selected element, or <code>null</code>
+		 */
+		public HashMap getElement(Selector selector) {
+			if (selector == null)
+				return null;
+
+			String element;
+			for (int i = 0; i < elements.size(); i++) {
+				// make pre-parse selector call
+				element = (String) elements.get(i);
+				if (selector.select(element)) {
+					// parse selected entry
+					HashMap attributes = new HashMap();
+					String elementName;
+					int j;
+					// parse out element name
+					for (j = 0; j < element.length(); j++) {
+						if (Character.isWhitespace(element.charAt(j)))
+							break;
+					}
+					if (j >= element.length()) {
+						elementName = element;
+					} else {
+						elementName = element.substring(0, j);
+						element = element.substring(j);
+						// parse out attributes
+						StringTokenizer t = new StringTokenizer(element, "=\""); //$NON-NLS-1$
+						boolean isKey = true;
+						String key = ""; //$NON-NLS-1$
+						while (t.hasMoreTokens()) {
+							String token = t.nextToken().trim();
+							if (!token.equals("")) { //$NON-NLS-1$
+								// collect (key, value) pairs
+								if (isKey) {
+									key = token;
+									isKey = false;
+								} else {
+									attributes.put(key, token);
+									isKey = true;
+								}
+							}
+						}
+					}
+					// make post-parse selector call
+					if (selector.select(elementName, attributes)) {
+						attributes.put("<element>", elementName); //$NON-NLS-1$
+						return attributes;
+					}
+				}
+			}
+			return null;
+		}
+
+		private void load(InputStream is) {
+			if (is == null)
+				return;
+
+			// read file
+			StringBuffer xml = new StringBuffer(4096);
+			char[] iobuf = new char[4096];
+			InputStreamReader r = null;
+			try {
+				r = new InputStreamReader(is);
+				int len = r.read(iobuf, 0, iobuf.length);
+				while (len != -1) {
+					xml.append(iobuf, 0, len);
+					len = r.read(iobuf, 0, iobuf.length);
+				}
+			} catch (Exception e) {
+				return;
+			} finally {
+				if (r != null)
+					try {
+						r.close();
+					} catch (IOException e) {
+						// ignore
+					}
+			}
+
+			// parse out element tokens
+			String xmlString = xml.toString();
+			StringTokenizer t = new StringTokenizer(xmlString, "<>"); //$NON-NLS-1$
+			while (t.hasMoreTokens()) {
+				String token = t.nextToken().trim();
+				if (!token.equals("")) //$NON-NLS-1$
+					elements.add(token);
+			}
+		}
+	}
+
+	public static class BootDescriptor {
+		private String id;
+		private String version;
+		private String[] libs;
+		private URL dir;
+
+		public BootDescriptor(String id, String version, String[] libs, URL dir) {
+			this.id = id;
+			this.version = version;
+			this.libs = libs;
+			this.dir = dir;
+		}
+
+		public String getId() {
+			return id;
+		}
+
+		public String getVersion() {
+			return version;
+		}
+
+		public String[] getLibraries() {
+			return libs;
+		}
+
+		public URL getPluginDirectoryURL() {
+			return dir;
+		}
+	}
+
+	private PlatformConfiguration(String configArg, String metaPath, URL pluginPath) throws IOException {
+		this.sites = new HashMap();
+		this.externalLinkSites = new HashMap();
+		this.cfgdFeatures = new HashMap();
+		this.bootPlugins = new HashMap();
+
+		// Determine configuration URL to use (based on command line argument)
+		URL configURL = null;
+		if (configArg != null && !configArg.trim().equals("")) { //$NON-NLS-1$
+			configURL = new URL(configArg);
+		}
+
+		// initialize configuration
+		boolean createRootSite = (pluginPath == null);
+		initializeCurrent(configURL, metaPath, createRootSite);
+
+		// merge in any plugin-path entries (converted to site(s))
+		if (pluginPath != null) {
+			updateConfigurationFromPlugins(pluginPath);
+		}
+
+		// pick up any first-time default settings (relative to install location)
+		loadInitializationAttributes();
+
+		// Detect external links. These are "soft link" to additional sites. The link
+		// files are usually provided by external installation programs. They are located
+		// relative to this configuration URL.
+		configureExternalLinks();
+
+		// Validate sites in the configuration. Causes any sites that do not exist to
+		// be removed from the configuration
+		validateSites();
+
+		// compute differences between configuration and actual content of the sites
+		// (base sites and link sites)
+		computeChangeStamp();
+
+		// determine which plugins we will use to start the rest of the "kernel"
+		// (need to get core.runtime matching the executing core.boot and
+		// xerces matching the selected core.runtime)
+		//		locateDefaultPlugins();
+	}
+
+	PlatformConfiguration(URL url) throws IOException {
+		this.sites = new HashMap();
+		this.externalLinkSites = new HashMap();
+		this.cfgdFeatures = new HashMap();
+		this.bootPlugins = new HashMap();
+		initialize(url);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#createSiteEntry(URL, ISitePolicy)
+	 */
+	public ISiteEntry createSiteEntry(URL url, ISitePolicy policy) {
+		return new PlatformConfiguration.SiteEntry(url, policy, this);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#createSitePolicy(int, String[])
+	 */
+	public ISitePolicy createSitePolicy(int type, String[] list) {
+		return new PlatformConfiguration.SitePolicy(type, list);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#createFeatureEntry(String, String, String, boolean, String, URL)
+	 */
+	public IFeatureEntry createFeatureEntry(String id, String version, String pluginVersion, boolean primary, String application, URL[] root) {
+		return new PlatformConfiguration.FeatureEntry(id, version, pluginVersion, primary, application, root);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#createFeatureEntry(String, String, String,
+	 * String, boolean, String, URL)
+	 */
+	public IFeatureEntry createFeatureEntry(String id, String version, String pluginIdentifier, String pluginVersion, boolean primary, String application, URL[] root) {
+		return new PlatformConfiguration.FeatureEntry(id, version, pluginIdentifier, pluginVersion, primary, application, root);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#configureSite(ISiteEntry)
+	 */
+	public void configureSite(ISiteEntry entry) {
+		configureSite(entry, false);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#configureSite(ISiteEntry, boolean)
+	 */
+	public synchronized void configureSite(ISiteEntry entry, boolean replace) {
+
+		if (entry == null)
+			return;
+
+		URL url = entry.getURL();
+		if (url == null)
+			return;
+		String key = url.toExternalForm();
+
+		if (sites.containsKey(key) && !replace)
+			return;
+
+		sites.put(key, entry);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#unconfigureSite(ISiteEntry)
+	 */
+	public synchronized void unconfigureSite(ISiteEntry entry) {
+		if (entry == null)
+			return;
+
+		URL url = entry.getURL();
+		if (url == null)
+			return;
+		String key = url.toExternalForm();
+
+		sites.remove(key);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getConfiguredSites()
+	 */
+	public ISiteEntry[] getConfiguredSites() {
+		if (sites.size() == 0)
+			return new ISiteEntry[0];
+
+		return (ISiteEntry[]) sites.values().toArray(new ISiteEntry[0]);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#findConfiguredSite(URL)
+	 */
+	public ISiteEntry findConfiguredSite(URL url) {
+		if (url == null)
+			return null;
+		String key = url.toExternalForm();
+
+		ISiteEntry result = (ISiteEntry) sites.get(key);
+		if (result == null) // retry with decoded URL string
+			result = (ISiteEntry) sites.get(URLDecoder.decode(key));
+		return result;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#configureFeatureEntry(IFeatureEntry)
+	 */
+	public synchronized void configureFeatureEntry(IFeatureEntry entry) {
+		if (entry == null)
+			return;
+
+		String key = entry.getFeatureIdentifier();
+		if (key == null)
+			return;
+
+		cfgdFeatures.put(key, entry);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#unconfigureFeatureEntry(IFeatureEntry)
+	 */
+	public synchronized void unconfigureFeatureEntry(IFeatureEntry entry) {
+		if (entry == null)
+			return;
+
+		String key = entry.getFeatureIdentifier();
+		if (key == null)
+			return;
+
+		cfgdFeatures.remove(key);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getConfiguredFeatureEntries()
+	 */
+	public IFeatureEntry[] getConfiguredFeatureEntries() {
+		if (cfgdFeatures.size() == 0)
+			return new IFeatureEntry[0];
+
+		return (IFeatureEntry[]) cfgdFeatures.values().toArray(new IFeatureEntry[0]);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#findConfiguredFeatureEntry(String)
+	 */
+	public IFeatureEntry findConfiguredFeatureEntry(String id) {
+		if (id == null)
+			return null;
+
+		return (IFeatureEntry) cfgdFeatures.get(id);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getConfigurationLocation()
+	 */
+	public URL getConfigurationLocation() {
+		return configLocation;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getChangeStamp()
+	 */
+	public long getChangeStamp() {
+		if (!changeStampIsValid)
+			computeChangeStamp();
+		return changeStamp;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getFeaturesChangeStamp()
+	 */
+	public long getFeaturesChangeStamp() {
+		if (!featuresChangeStampIsValid)
+			computeFeaturesChangeStamp();
+		return featuresChangeStamp;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getPluginsChangeStamp()
+	 */
+	public long getPluginsChangeStamp() {
+		if (!pluginsChangeStampIsValid)
+			computePluginsChangeStamp();
+		return pluginsChangeStamp;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getApplicationIdentifier()
+	 */
+	public String getApplicationIdentifier() {
+
+		if (cmdInitialize) {
+			// we are running post-install initialization. Force
+			// running of the reconciler
+			return RECONCILER_APP;
+		}
+
+		if (featuresChangeStamp != lastFeaturesChangeStamp) {
+			// we have detected feature changes ... see if we need to reconcile
+			boolean update = !cmdNoUpdate || cmdUpdate;
+			if (update)
+				return RECONCILER_APP;
+		}
+
+		// "normal" startup ... run specified application
+		return getApplicationIdentifierInternal();
+	}
+
+	private String getApplicationIdentifierInternal() {
+
+		if (cmdApplication != null) // application was specified
+			return cmdApplication;
+		else {
+			// if -feature was not specified use the default feature
+			String feature = cmdFeature;
+			if (feature == null)
+				feature = defaultFeature;
+
+			// lookup application for feature (specified or defaulted)
+			if (feature != null) {
+				IFeatureEntry fe = findConfiguredFeatureEntry(feature);
+				if (fe != null) {
+					if (fe.getFeatureApplication() != null)
+						return fe.getFeatureApplication();
+				}
+			}
+		}
+
+		// return hardcoded default if we failed
+		return DEFAULT_FEATURE_APPLICATION;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getPrimaryFeatureIdentifier()
+	 */
+	public String getPrimaryFeatureIdentifier() {
+
+		if (cmdFeature != null) // -feature was specified on command line
+			return cmdFeature;
+
+		// feature was not specified on command line
+		if (defaultFeature != null)
+			return defaultFeature; // return customized default if set
+		else
+			return DEFAULT_FEATURE_ID; // return hardcoded default
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getPluginPath()
+	 */
+	public URL[] getPluginPath() {
+		ArrayList path = new ArrayList();
+		if (DEBUG)
+			debug("computed plug-in path:"); //$NON-NLS-1$
+
+		ISiteEntry[] sites = getConfiguredSites();
+		URL pathURL;
+		for (int i = 0; i < sites.length; i++) {
+			String[] plugins = sites[i].getPlugins();
+			for (int j = 0; j < plugins.length; j++) {
+				try {
+					pathURL = new URL(((SiteEntry) sites[i]).getResolvedURL(), plugins[j]);
+					path.add(pathURL);
+					if (DEBUG)
+						debug("   " + pathURL.toString()); //$NON-NLS-1$
+				} catch (MalformedURLException e) {
+					// skip entry ...
+					if (DEBUG)
+						debug("   bad URL: " + e); //$NON-NLS-1$
+				}
+			}
+		}
+		return (URL[]) path.toArray(new URL[0]);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#getBootstrapPluginIdentifiers()
+	 */
+	public String[] getBootstrapPluginIdentifiers() {
+		return BOOTSTRAP_PLUGINS;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#setBootstrapPluginLocation(String, URL)
+	 */
+	public void setBootstrapPluginLocation(String id, URL location) {
+		String[] ids = getBootstrapPluginIdentifiers();
+		for (int i = 0; i < ids.length; i++) {
+			if (ids[i].equals(id)) {
+				bootPlugins.put(id, location.toExternalForm());
+				break;
+			}
+		}
+	}
+
+	/*
+	 * @see IPlatformConfiguration#isUpdateable()
+	 */
+	public boolean isUpdateable() {
+		return true;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#isTransient()
+	 */
+	public boolean isTransient() {
+		return transientConfig;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#isTransient(boolean)
+	 */
+	public void isTransient(boolean value) {
+		//		if (this != BootLoader.getCurrentPlatformConfiguration())
+		//			transientConfig = value;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#refresh()
+	 */
+	public synchronized void refresh() {
+		// Reset computed values. Will be lazily refreshed
+		// on next access
+		ISiteEntry[] sites = getConfiguredSites();
+		for (int i = 0; i < sites.length; i++) {
+			// reset site entry
+			 ((SiteEntry) sites[i]).refresh();
+		}
+		// reset configuration entry.
+		lastChangeStamp = changeStamp;
+		lastFeaturesChangeStamp = featuresChangeStamp;
+		lastPluginsChangeStamp = pluginsChangeStamp;
+		changeStampIsValid = false;
+		featuresChangeStampIsValid = false;
+		pluginsChangeStampIsValid = false;
+	}
+
+	/*
+	 * @see IPlatformConfiguration#save()
+	 */
+	public void save() throws IOException {
+		if (isUpdateable())
+			save(configLocation);
+	}
+
+	/*
+	 * @see IPlatformConfiguration#save(URL)
+	 */
+	public synchronized void save(URL url) throws IOException {
+		if (url == null)
+			throw new IOException(Policy.bind("cfig.unableToSave.noURL")); //$NON-NLS-1$
+
+		PrintWriter w = null;
+		OutputStream os = null;
+		if (!url.getProtocol().equals("file")) { //$NON-NLS-1$
+			// not a file protocol - attempt to save to the URL
+			URLConnection uc = url.openConnection();
+			uc.setDoOutput(true);
+			os = uc.getOutputStream();
+			w = new PrintWriter(os);
+			try {
+				write(w);
+			} finally {
+				w.close();
+			}
+		} else {
+			// file protocol - do safe i/o
+			File cfigFile = new File(url.getFile().replace('/', File.separatorChar));
+			File cfigDir = cfigFile.getParentFile();
+			if (cfigDir != null)
+				cfigDir.mkdirs();
+
+			// first save the file as temp
+			File cfigTmp = new File(cfigFile.getAbsolutePath() + CONFIG_FILE_TEMP_SUFFIX);
+			os = new FileOutputStream(cfigTmp);
+			w = new PrintWriter(os);
+			try {
+				write(w);
+			} finally {
+				w.close();
+			}
+
+			// make sure we actually succeeded saving the whole configuration.
+			InputStream is = new FileInputStream(cfigTmp);
+			Properties tmpProps = new Properties();
+			try {
+				tmpProps.load(is);
+				if (!EOF.equals(tmpProps.getProperty(EOF))) {
+					throw new IOException(Policy.bind("cfig.unableToSave", cfigTmp.getAbsolutePath())); //$NON-NLS-1$
+				}
+			} finally {
+				is.close();
+			}
+
+			// make the saved config the "active" one
+			File cfigBak = new File(cfigFile.getAbsolutePath() + CONFIG_FILE_BAK_SUFFIX);
+			cfigBak.delete(); // may have old .bak due to prior failure
+
+			if (cfigFile.exists())
+				cfigFile.renameTo(cfigBak);
+
+			// at this point we have old config (if existed) as "bak" and the
+			// new config as "tmp".
+			boolean ok = cfigTmp.renameTo(cfigFile);
+			if (ok) {
+				// at this point we have the new config "activated", and the old
+				// config (if it existed) as "bak"
+				cfigBak.delete(); // clean up
+			} else {
+				// this codepath represents a tiny failure window. The load processing
+				// on startup will detect missing config and will attempt to start
+				// with "tmp" (latest), then "bak" (the previous). We can also end up
+				// here if we failed to rename the current config to "bak". In that
+				// case we will restart with the previous state.
+				throw new IOException(Policy.bind("cfig.unableToSave", cfigTmp.getAbsolutePath())); //$NON-NLS-1$
+			}
+		}
+	}
+
+	public BootDescriptor getPluginBootDescriptor(String id) {
+		// return the plugin descriptor for the specified plugin. This method
+		// is used during boot processing to obtain information about "kernel" plugins
+		// whose class loaders must be created prior to the plugin registry being
+		// available (ie. loaders needed to create the plugin registry).
+
+		if (RUNTIME_PLUGIN_ID.equals(id))
+			return runtimeDescriptor;
+		else
+			return null;
+	}
+
+	static PlatformConfiguration getCurrent() {
+		return currentPlatformConfiguration;
+	}
+
+	/**
+	 * Create and initialize the current platform configuration
+	 * @param cmdArgs command line arguments (startup and boot arguments are
+	 * already consumed)
+	 * @param r10plugins plugin-path URL as passed on the BootLoader.run(...)
+	 * or BootLoader.startup(...) method. Supported for R1.0 compatibility
+	 * @param r10apps application identifies as passed on the BootLoader.run(...)
+	 * method. Supported for R1.0 compatibility.
+	 * @param metaPath path to the platform metadata area
+	 */
+	static synchronized String[] startup(String[] cmdArgs, URL r10plugins, String r10app, String metaPath, URL installURL) throws Exception {
+		PlatformConfiguration.installURL = installURL;
+
+		// if BootLoader was invoked directly (rather than via Main), it is possible
+		// to have the plugin-path and application set in 2 ways: (1) via an explicit
+		// argument on the invocation method, or (2) via a command line argument (passed
+		// into this method as the argument String[]). If specified, the explicit
+		// values are used even if the command line arguments were specified as well.
+		cmdPlugins = r10plugins; // R1.0 compatibility
+		cmdApplication = r10app; // R1.0 compatibility
+
+		// process command line arguments
+		String[] passthruArgs = processCommandLine(cmdArgs);
+		if (cmdDev)
+			cmdNoUpdate = true; // force -noupdate when in dev mode (eg. PDE)
+
+		// create current configuration
+		if (currentPlatformConfiguration == null)
+			currentPlatformConfiguration = new PlatformConfiguration(cmdConfiguration, metaPath, cmdPlugins);
+
+		// check if we will be forcing reconciliation
+		passthruArgs = checkForFeatureChanges(passthruArgs, currentPlatformConfiguration);
+
+		// check if we should indicate new changes
+		passthruArgs = checkForNewUpdates(currentPlatformConfiguration, passthruArgs);
+
+		return passthruArgs;
+	}
+
+	static synchronized void shutdown() throws IOException {
+
+		// save platform configuration
+		PlatformConfiguration config = getCurrent();
+		if (config != null) {
+			try {
+				config.save();
+			} catch (IOException e) {
+				if (DEBUG)
+					debug("Unable to save configuration " + e.toString()); //$NON-NLS-1$
+				// will recover on next startup
+			}
+			config.clearConfigurationLock();
+		}
+	}
+
+	private synchronized void initializeCurrent(URL url, String metaPath, boolean createRootSite) throws IOException {
+		// FIXME: commented out for now. Remove if not needed.
+		//boolean concurrentUse = false;
+
+		if (cmdInitialize) {
+			// we are running post-install initialization (-install command
+			// line argument). Ignore any configuration URL passed in.
+			// Force the configuration to be saved in the install location.
+			// Allow an existing configuration to be re-initialized.
+			url = new URL(getInstallURL(), CONFIG_FILE); // if we fail here, return exception
+			// FIXME: commented out for now. Remove if not needed. 
+			// I left the call to #getConfigurationLock in just in case
+			// calling it has useful side effect. If not, then it can be removed too.
+			//concurrentUse = getConfigurationLock(url);
+			getConfigurationLock(url);
+
+			resetInitializationConfiguration(url); // [20111]
+			if (createRootSite)
+				configureSite(getRootSite());
+			if (DEBUG)
+				debug("Initializing configuration " + url.toString()); //$NON-NLS-1$
+			configLocation = url;
+			verifyPath(configLocation);
+			return;
+		}
+
+		if (url != null) {
+			// configuration URL was specified. Use it (if exists), or create one
+			// in specified location
+
+			// check concurrent use lock
+			// FIXME: might not need this method call.
+			getConfigurationLock(url);
+
+			// try loading the configuration
+			try {
+				load(url);
+				if (DEBUG)
+					debug("Using configuration " + url.toString()); //$NON-NLS-1$
+			} catch (IOException e) {
+				cmdFirstUse = true;
+				if (createRootSite)
+					configureSite(getRootSite());
+				if (DEBUG)
+					debug("Creating configuration " + url.toString()); //$NON-NLS-1$
+			}
+			configLocation = url;
+			verifyPath(configLocation);
+			return;
+
+		} else {
+			// configuration URL was not specified. Default behavior is to look
+			// for configuration in the workspace meta area. If not found, look
+			// for pre-initialized configuration in the installation location.
+			// If it is found it is used as the initial configuration. Otherwise
+			// a new configuration is created. In either case the resulting
+			// configuration is written into the default state area.
+			// The default state area is computed as follows:
+			// 1) We store the config state relative to the 'eclipse' directory if possible
+			// 2) If this directory is read-only OR 
+			//    if shared install is desired (using command line argument -shared), 
+			//    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.
+
+			//	if we fail here, return exception
+			URL defaultStateURL = getDefaultStateLocation();
+			URL cfigURL = new URL(defaultStateURL, CONFIG_FILE);
+
+			// check concurrent use lock
+			// FIXME: might not need this method call
+			getConfigurationLock(cfigURL);
+
+			// if we can load it, use it
+			try {
+				load(cfigURL);
+				configLocation = cfigURL;
+				verifyPath(configLocation);
+				if (DEBUG)
+					debug("Using configuration " + configLocation.toString()); //$NON-NLS-1$
+				return;
+			} catch (IOException e) {
+				cmdFirstUse = true; // we are creating new configuration
+			}
+
+			// failed to load, see if we can find pre-initialized configuration.
+			// Don't attempt this initialization when self-hosting (is unpredictable)
+			if (createRootSite) {
+				try {
+					url = new URL(getInstallURL(), CONFIG_FILE);
+					load(url);
+					// pre-initialized config loaded OK ... copy any remaining update metadata
+					// Only copy if the default config location is not the install location
+					if (getInstallURL() != defaultStateURL)
+						copyInitializedState(getInstallURL(), defaultStateURL.getFile(), CONFIG_DIR);
+					configLocation = cfigURL; // config in default location is the right URL
+					verifyPath(configLocation);
+					if (DEBUG) {
+						debug("Using configuration " + configLocation.toString()); //$NON-NLS-1$
+						debug("Initialized from    " + url.toString()); //$NON-NLS-1$
+					}
+					return;
+				} catch (IOException e) {
+					// continue ...
+				}
+			}
+
+			// if load failed, initialize with default site info
+			if (createRootSite)
+				configureSite(getRootSite());
+			configLocation = cfigURL;
+			verifyPath(configLocation);
+			if (DEBUG)
+				debug("Creating configuration " + configLocation.toString()); //$NON-NLS-1$
+			return;
+		}
+	}
+
+	private synchronized void initialize(URL url) throws IOException {
+		if (url == null) {
+			if (DEBUG)
+				debug("Creating empty configuration object"); //$NON-NLS-1$
+			return;
+		}
+
+		load(url);
+		configLocation = url;
+		if (DEBUG)
+			debug("Using configuration " + configLocation.toString()); //$NON-NLS-1$
+	}
+
+	private ISiteEntry getRootSite() {
+		// create default site entry for the root
+		ISitePolicy defaultPolicy = createSitePolicy(DEFAULT_POLICY_TYPE, DEFAULT_POLICY_LIST);
+		URL siteURL = null;
+		try {
+			siteURL = new URL(PlatformURLHandler.PROTOCOL + PlatformURLHandler.PROTOCOL_SEPARATOR + "/" + "base" + "/"); //$NON-NLS-1$ //$NON-NLS-2$ // try using platform-relative URL
+		} catch (MalformedURLException e) {
+			siteURL = getInstallURL(); // ensure we come up ... use absolute file URL
+		}
+		ISiteEntry defaultSite = createSiteEntry(siteURL, defaultPolicy);
+		return defaultSite;
+	}
+
+	private void resetInitializationConfiguration(URL url) throws IOException {
+		// [20111]
+		if (!supportsDetection(url))
+			return; // can't do ...
+
+		URL resolved = resolvePlatformURL(url);
+		File initCfg = new File(resolved.getFile().replace('/', File.separatorChar));
+		File initDir = initCfg.getParentFile();
+		resetInitializationLocation(initDir);
+	}
+
+	private void resetInitializationLocation(File dir) {
+		// [20111]
+		if (dir == null || !dir.exists() || !dir.isDirectory())
+			return;
+		File[] list = dir.listFiles();
+		for (int i = 0; i < list.length; i++) {
+			if (list[i].isDirectory())
+				resetInitializationLocation(list[i]);
+			list[i].delete();
+		}
+	}
+
+	private boolean getConfigurationLock(URL url) {
+		if (configurationInWorkspace(url))
+			return false;
+
+		if (!url.getProtocol().equals("file")) //$NON-NLS-1$
+			return false;
+
+		verifyPath(url);
+		String cfgName = url.getFile().replace('/', File.separatorChar);
+		String lockName = cfgName + CONFIG_FILE_LOCK_SUFFIX;
+		cfgLockFile = new File(lockName);
+
+		//if the lock file already exists, try to delete,
+		//assume failure means another eclipse has it open
+		if (cfgLockFile.exists())
+			cfgLockFile.delete();
+		if (cfgLockFile.exists()) {
+			throw new RuntimeException(Policy.bind("cfig.inUse", cfgName, lockName)); //$NON-NLS-1$
+		}
+
+		// OK so far ... open the lock file so other instances will fail
+		try {
+			cfgLockFileRAF = new RandomAccessFile(cfgLockFile, "rw"); //$NON-NLS-1$
+			cfgLockFileRAF.writeByte(0);
+		} catch (IOException e) {
+			throw new RuntimeException(Policy.bind("cfig.failCreateLock", cfgName)); //$NON-NLS-1$
+		}
+
+		return false;
+	}
+
+	private void clearConfigurationLock() {
+		try {
+			if (cfgLockFileRAF != null) {
+				cfgLockFileRAF.close();
+				cfgLockFileRAF = null;
+			}
+		} catch (IOException e) {
+			// ignore ...
+		}
+		if (cfgLockFile != null) {
+			cfgLockFile.delete();
+			cfgLockFile = null;
+		}
+	}
+
+	private boolean configurationInWorkspace(URL url) {
+		// the configuration file is now in the workspace, so return true
+		return true;
+	}
+
+	private void computeChangeStamp() {
+		computeFeaturesChangeStamp();
+		computePluginsChangeStamp();
+		changeStamp = featuresChangeStamp ^ pluginsChangeStamp;
+		changeStampIsValid = true;
+	}
+
+	private void computeFeaturesChangeStamp() {
+		if (featuresChangeStampIsValid)
+			return;
+
+		long result = 0;
+		ISiteEntry[] sites = getConfiguredSites();
+		for (int i = 0; i < sites.length; i++) {
+			result ^= sites[i].getFeaturesChangeStamp();
+		}
+		featuresChangeStamp = result;
+		featuresChangeStampIsValid = true;
+	}
+
+	private void computePluginsChangeStamp() {
+		if (pluginsChangeStampIsValid)
+			return;
+
+		long result = 0;
+		ISiteEntry[] sites = getConfiguredSites();
+		for (int i = 0; i < sites.length; i++) {
+			result ^= sites[i].getPluginsChangeStamp();
+		}
+		pluginsChangeStamp = result;
+		pluginsChangeStampIsValid = true;
+	}
+
+	private void configureExternalLinks() {
+		URL linkURL = getInstallURL();
+		if (!supportsDetection(linkURL))
+			return;
+
+		try {
+			linkURL = new URL(linkURL, LINKS + "/"); //$NON-NLS-1$
+		} catch (MalformedURLException e) {
+			// skip bad links ...
+			if (DEBUG)
+				debug("Unable to obtain link URL"); //$NON-NLS-1$
+			return;
+		}
+
+		File linkDir = new File(linkURL.getFile());
+		File[] links = linkDir.listFiles();
+		if (links == null || links.length == 0) {
+			if (DEBUG)
+				debug("No links detected in " + linkURL.toExternalForm()); //$NON-NLS-1$
+			return;
+		}
+
+		for (int i = 0; i < links.length; i++) {
+			if (links[i].isDirectory())
+				continue;
+			if (DEBUG)
+				debug("Link file " + links[i].getAbsolutePath()); //$NON-NLS-1$
+			Properties props = new Properties();
+			FileInputStream is = null;
+			try {
+				is = new FileInputStream(links[i]);
+				props.load(is);
+				configureExternalLinkSites(links[i], props);
+			} catch (IOException e) {
+				// skip bad links ...
+				if (DEBUG)
+					debug("   unable to load link file " + e); //$NON-NLS-1$
+				continue;
+			} finally {
+				if (is != null) {
+					try {
+						is.close();
+					} catch (IOException e) {
+						// ignore ...
+					}
+				}
+			}
+		}
+	}
+
+	private void configureExternalLinkSites(File linkFile, Properties props) {
+		String path = props.getProperty(LINK_PATH);
+		if (path == null) {
+			if (DEBUG)
+				debug("   no path definition"); //$NON-NLS-1$
+			return;
+		}
+
+		String link;
+		boolean updateable = true;
+		URL siteURL;
+		SiteEntry linkSite;
+		ISitePolicy linkSitePolicy = createSitePolicy(DEFAULT_POLICY_TYPE, DEFAULT_POLICY_LIST);
+
+		// parse out link information
+		if (path.startsWith(LINK_READ + " ")) { //$NON-NLS-1$
+			updateable = false;
+			link = path.substring(2).trim();
+		} else if (path.startsWith(LINK_READ_WRITE + " ")) { //$NON-NLS-1$
+			link = path.substring(3).trim();
+		} else {
+			link = path;
+		}
+
+		// 	make sure we have a valid link specification
+		try {
+			if (!link.endsWith(File.separator))
+				link += File.separator;
+			File target = new File(link + ECLIPSE);
+			link = "file:" + target.getAbsolutePath().replace(File.separatorChar, '/'); //$NON-NLS-1$
+			if (!link.endsWith("/")) //$NON-NLS-1$
+				link += "/"; // sites must be directories //$NON-NLS-1$
+			siteURL = new URL(link);
+		} catch (MalformedURLException e) {
+			// ignore bad links ...
+			if (DEBUG)
+				debug("  bad URL " + e); //$NON-NLS-1$
+			return;
+		}
+
+		// process the link
+		linkSite = (SiteEntry) externalLinkSites.get(siteURL);
+		if (linkSite != null) {
+			// we already have a site for this link target, update it if needed
+			linkSite.updateable = updateable;
+			linkSite.linkFileName = linkFile.getAbsolutePath();
+		} else {
+			// this is a link to a new target so create site for it
+			linkSite = (SiteEntry) createSiteEntry(siteURL, linkSitePolicy);
+			linkSite.updateable = updateable;
+			linkSite.linkFileName = linkFile.getAbsolutePath();
+		}
+
+		// configure the new site
+		// NOTE: duplicates are not replaced (first one in wins)
+		configureSite(linkSite);
+		if (DEBUG)
+			debug("   " + (updateable ? "R/W -> " : "R/O -> ") + siteURL.toString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	}
+
+	/*
+	 * compute site(s) from plugin-path and merge into specified configuration
+	 */
+	private void updateConfigurationFromPlugins(URL file) throws IOException {
+
+		// get the actual plugin path
+		URL[] pluginPath = Utils.getPluginPath(file);
+		if (pluginPath == null || pluginPath.length == 0)
+			return;
+
+		// create a temp configuration and populate it based on plugin path
+		PlatformConfiguration tempConfig = new PlatformConfiguration((URL) null);
+		for (int i = 0; i < pluginPath.length; i++) {
+			String entry = pluginPath[i].toExternalForm();
+			String sitePortion;
+			String pluginPortion;
+			int ix;
+			if (entry.endsWith("/")) { //$NON-NLS-1$
+				// assume directory path in the form <site>/plugins/
+				// look for -------------------------------^
+				ix = findEntrySeparator(entry, 2); // second from end
+				sitePortion = entry.substring(0, ix + 1);
+				pluginPortion = entry.substring(ix + 1);
+				if (!pluginPortion.equals("plugins/")) //$NON-NLS-1$
+					continue; // unsupported entry ... skip it ("fragments/" are handled)
+				pluginPortion = null;
+			} else {
+				// assume full path in the form <site>/<pluginsDir>/<some.plugin>/plugin.xml
+				// look for --------------------------^
+				ix = findEntrySeparator(entry, 3); // third from end
+				sitePortion = entry.substring(0, ix + 1);
+				pluginPortion = entry.substring(ix + 1);
+			}
+			if (ix == -1)
+				continue; // bad entry ... skip it
+
+			URL siteURL = null;
+			try {
+				siteURL = new URL(sitePortion);
+				if (siteURL.getProtocol().equals("file")) { //$NON-NLS-1$
+					File sf = new File(siteURL.getFile());
+					String sfn = sf.getAbsolutePath().replace(File.separatorChar, '/');
+					if (!sfn.endsWith("/")) //$NON-NLS-1$
+						sfn += "/"; //$NON-NLS-1$
+					siteURL = new URL("file:" + sfn); //$NON-NLS-1$
+				}
+			} catch (MalformedURLException e) {
+				continue; // bad entry ... skip it
+			}
+
+			// configure existing site or create a new one for the entry
+			ISiteEntry site = tempConfig.findConfiguredSite(siteURL);
+			ISitePolicy policy;
+			if (site == null) {
+				// new site
+				if (pluginPortion == null)
+					policy = tempConfig.createSitePolicy(ISitePolicy.USER_EXCLUDE, null);
+				else
+					policy = tempConfig.createSitePolicy(ISitePolicy.USER_INCLUDE, new String[] { pluginPortion });
+				site = tempConfig.createSiteEntry(siteURL, policy);
+				tempConfig.configureSite(site);
+			} else {
+				// existing site
+				policy = site.getSitePolicy();
+				if (policy.getType() == ISitePolicy.USER_EXCLUDE)
+					continue; // redundant entry ... skip it
+				if (pluginPortion == null) {
+					// directory entry ... change policy to exclusion (with empty list)
+					policy = tempConfig.createSitePolicy(ISitePolicy.USER_EXCLUDE, null);
+				} else {
+					// explicit entry ... add it to the inclusion list
+					ArrayList list = new ArrayList(Arrays.asList(policy.getList()));
+					list.add(pluginPortion);
+					policy = tempConfig.createSitePolicy(ISitePolicy.USER_INCLUDE, (String[]) list.toArray(new String[0]));
+				}
+				site.setSitePolicy(policy);
+			}
+		}
+
+		// merge resulting site(s) into the specified configuration
+		ISiteEntry[] tempSites = tempConfig.getConfiguredSites();
+		for (int i = 0; i < tempSites.length; i++) {
+			configureSite(tempSites[i], true /*replace*/
+			);
+		}
+	}
+
+	private void validateSites() {
+
+		// check to see if all sites are valid. Remove any sites that do not exist.
+		SiteEntry[] list = (SiteEntry[]) sites.values().toArray(new SiteEntry[0]);
+		for (int i = 0; i < list.length; i++) {
+			URL siteURL = list[i].getResolvedURL();
+			if (!supportsDetection(siteURL))
+				continue;
+
+			File siteRoot = new File(siteURL.getFile().replace('/', File.separatorChar));
+			if (!siteRoot.exists()) {
+				unconfigureSite(list[i]);
+				if (DEBUG)
+					debug("Site " + siteURL + " does not exist ... removing from configuration"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+	}
+
+	private void copyInitializedState(URL source, String target, String dir) {
+		try {
+			if (!source.getProtocol().equals("file")) //$NON-NLS-1$
+				return; // need to be able to do "dir"
+
+			copy(new File(source.getFile()), new File(target), dir);
+
+		} catch (IOException e) {
+			// this is an optimistic copy. If we fail, the state will be reconciled
+			// when the update manager is triggered.
+		}
+	}
+
+	private void copy(File srcDir, File tgtDir, String extraPath) throws IOException {
+		File src = new File(srcDir, extraPath);
+		File tgt = new File(tgtDir, extraPath);
+
+		if (src.isDirectory()) {
+			// copy content of directories
+			tgt.mkdir();
+			String[] list = src.list();
+			if (list == null)
+				return;
+			for (int i = 0; i < list.length; i++) {
+				copy(srcDir, tgtDir, extraPath + File.separator + list[i]);
+			}
+		} else {
+			// copy individual files
+			FileInputStream is = null;
+			FileOutputStream os = null;
+			try {
+				is = new FileInputStream(src);
+				os = new FileOutputStream(tgt);
+				byte[] buff = new byte[1024];
+				int count = is.read(buff);
+				while (count != -1) {
+					os.write(buff, 0, count);
+					count = is.read(buff);
+				}
+			} catch (IOException e) {
+				// continue ... update reconciler will have to reconstruct state
+			} finally {
+				if (is != null)
+					try {
+						is.close();
+					} catch (IOException e) {
+						// ignore ...
+					}
+				if (os != null)
+					try {
+						os.close();
+					} catch (IOException e) {
+						// ignore ...
+					}
+			}
+		}
+	}
+
+	private void load(URL url) throws IOException {
+
+		if (url == null)
+			throw new IOException(Policy.bind("cfig.unableToLoad.noURL")); //$NON-NLS-1$
+
+		// try to load saved configuration file (watch for failed prior save())
+		Properties props = null;
+		IOException originalException = null;
+		try {
+			props = loadProperties(url, null); // try to load config file
+		} catch (IOException e1) {
+			originalException = e1;
+			try {
+				props = loadProperties(url, CONFIG_FILE_TEMP_SUFFIX); // check for failures on save
+			} catch (IOException e2) {
+				try {
+					props = loadProperties(url, CONFIG_FILE_BAK_SUFFIX); // check for failures on save
+				} catch (IOException e3) {
+					throw originalException; // we tried, but no config here ...
+				}
+			}
+		}
+
+		// check version
+		String v = props.getProperty(CFG_VERSION);
+		if (!VERSION.equals(v)) {
+			// the state is invalid, delete any files under the directory
+			// bug 33493
+			resetUpdateManagerState(url);
+			throw new IOException(Policy.bind("cfig.badVersion", v)); //$NON-NLS-1$
+		}
+
+		// load simple properties
+		defaultFeature = loadAttribute(props, CFG_FEATURE_ENTRY_DEFAULT, null);
+
+		String flag = loadAttribute(props, CFG_TRANSIENT, null);
+		if (flag != null) {
+			if (flag.equals("true")) //$NON-NLS-1$
+				transientConfig = true;
+			else
+				transientConfig = false;
+		}
+
+		String stamp = loadAttribute(props, CFG_STAMP, null);
+		if (stamp != null) {
+			try {
+				lastChangeStamp = Long.parseLong(stamp);
+			} catch (NumberFormatException e) {
+				// ignore bad attribute ...
+			}
+		}
+
+		stamp = loadAttribute(props, CFG_FEATURE_STAMP, null);
+		if (stamp != null) {
+			try {
+				lastFeaturesChangeStamp = Long.parseLong(stamp);
+			} catch (NumberFormatException e) {
+				// ignore bad attribute ...
+			}
+		}
+
+		stamp = loadAttribute(props, CFG_PLUGIN_STAMP, null);
+		if (stamp != null) {
+			try {
+				lastPluginsChangeStamp = Long.parseLong(stamp);
+			} catch (NumberFormatException e) {
+				// ignore bad attribute ...
+			}
+		}
+
+		// load bootstrap entries
+		String[] ids = getBootstrapPluginIdentifiers();
+		for (int i = 0; i < ids.length; i++) {
+			bootPlugins.put(ids[i], loadAttribute(props, CFG_BOOT_PLUGIN + "." + ids[i], null)); //$NON-NLS-1$
+		}
+
+		// load feature entries
+		IFeatureEntry fe = loadFeatureEntry(props, CFG_FEATURE_ENTRY + ".0", null); //$NON-NLS-1$
+		for (int i = 1; fe != null; i++) {
+			configureFeatureEntry(fe);
+			fe = loadFeatureEntry(props, CFG_FEATURE_ENTRY + "." + i, null); //$NON-NLS-1$
+		}
+
+		// load site properties
+		SiteEntry root = (SiteEntry) getRootSite();
+		String rootUrlString = root.getURL().toExternalForm();
+		SiteEntry se = (SiteEntry) loadSite(props, CFG_SITE + ".0", null); //$NON-NLS-1$
+		for (int i = 1; se != null; i++) {
+
+			// check if we are forcing "first use" processing with an existing
+			// platform.cfg. In this case ignore site entry that represents
+			// the platform install, and use a root site entry in its place.
+			// This ensures we do not get messed up by an exclusion list that
+			// is read from the prior state.
+			if (cmdFirstUse && rootUrlString.equals(se.getURL().toExternalForm()))
+				se = root;
+
+			if (!se.isExternallyLinkedSite())
+				configureSite(se);
+			else
+				// remember external link site state, but do not configure at this point
+				externalLinkSites.put(se.getURL(), se);
+			se = (SiteEntry) loadSite(props, CFG_SITE + "." + i, null); //$NON-NLS-1$
+		}
+	}
+
+	private Properties loadProperties(URL url, String suffix) throws IOException {
+
+		// figure out what we will be loading
+		if (suffix != null && !suffix.equals("")) //$NON-NLS-1$
+			url = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + suffix);
+
+		// try to load saved configuration file
+		Properties props = new Properties();
+		InputStream is = null;
+		try {
+			is = url.openStream();
+			props.load(is);
+			// check to see if we have complete config file
+			if (!EOF.equals(props.getProperty(EOF))) {
+				throw new IOException(Policy.bind("cfig.unableToLoad.incomplete", url.toString())); //$NON-NLS-1$
+			}
+		} finally {
+			if (is != null) {
+				try {
+					is.close();
+				} catch (IOException e) {
+					// ignore ...
+				}
+			}
+		}
+		return props;
+	}
+
+	private ISiteEntry loadSite(Properties props, String name, ISiteEntry dflt) {
+
+		String urlString = loadAttribute(props, name + "." + CFG_URL, null); //$NON-NLS-1$
+		if (urlString == null)
+			return dflt;
+
+		URL url = null;
+		try {
+			url = new URL(urlString);
+		} catch (MalformedURLException e) {
+			return dflt;
+		}
+
+		int policyType;
+		String[] policyList;
+		String typeString = loadAttribute(props, name + "." + CFG_POLICY, null); //$NON-NLS-1$
+		if (typeString == null) {
+			policyType = DEFAULT_POLICY_TYPE;
+			policyList = DEFAULT_POLICY_LIST;
+		} else {
+			int i;
+			for (i = 0; i < CFG_POLICY_TYPE.length; i++) {
+				if (typeString.equals(CFG_POLICY_TYPE[i])) {
+					break;
+				}
+			}
+			if (i >= CFG_POLICY_TYPE.length) {
+				policyType = DEFAULT_POLICY_TYPE;
+				policyList = DEFAULT_POLICY_LIST;
+			} else {
+				policyType = i;
+				policyList = loadListAttribute(props, name + "." + CFG_LIST, new String[0]); //$NON-NLS-1$
+			}
+		}
+
+		ISitePolicy sp = createSitePolicy(policyType, policyList);
+		SiteEntry site = (SiteEntry) createSiteEntry(url, sp);
+
+		String stamp = loadAttribute(props, name + "." + CFG_STAMP, null); //$NON-NLS-1$
+		if (stamp != null) {
+			try {
+				site.lastChangeStamp = Long.parseLong(stamp);
+			} catch (NumberFormatException e) {
+				// ignore bad attribute ...
+			}
+		}
+
+		stamp = loadAttribute(props, name + "." + CFG_FEATURE_STAMP, null); //$NON-NLS-1$
+		if (stamp != null) {
+			try {
+				site.lastFeaturesChangeStamp = Long.parseLong(stamp);
+			} catch (NumberFormatException e) {
+				// ignore bad attribute ...
+			}
+		}
+
+		stamp = loadAttribute(props, name + "." + CFG_PLUGIN_STAMP, null); //$NON-NLS-1$
+		if (stamp != null) {
+			try {
+				site.lastPluginsChangeStamp = Long.parseLong(stamp);
+			} catch (NumberFormatException e) {
+				// ignore bad attribute ...
+			}
+		}
+
+		String flag = loadAttribute(props, name + "." + CFG_UPDATEABLE, null); //$NON-NLS-1$
+		if (flag != null) {
+			if (flag.equals("true")) //$NON-NLS-1$
+				site.updateable = true;
+			else
+				site.updateable = false;
+		}
+
+		String linkname = loadAttribute(props, name + "." + CFG_LINK_FILE, null); //$NON-NLS-1$
+		if (linkname != null && !linkname.equals("")) { //$NON-NLS-1$
+			site.linkFileName = linkname.replace('/', File.separatorChar);
+		}
+
+		return site;
+	}
+
+	private IFeatureEntry loadFeatureEntry(Properties props, String name, IFeatureEntry dflt) {
+		String id = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_ID, null); //$NON-NLS-1$
+		if (id == null)
+			return dflt;
+		String version = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_VERSION, null); //$NON-NLS-1$
+		String pluginVersion = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_PLUGIN_VERSION, null); //$NON-NLS-1$
+		if (pluginVersion == null)
+			pluginVersion = version;
+		String pluginIdentifier = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_PLUGIN_IDENTIFIER, null); //$NON-NLS-1$
+		if (pluginIdentifier == null)
+			pluginIdentifier = id;
+		String application = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_APPLICATION, null); //$NON-NLS-1$
+		ArrayList rootList = new ArrayList();
+
+		// get install locations
+		String rootString = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_ROOT + ".0", null); //$NON-NLS-1$ //$NON-NLS-2$
+		for (int i = 1; rootString != null; i++) {
+			try {
+				URL rootEntry = new URL(rootString);
+				rootList.add(rootEntry);
+			} catch (MalformedURLException e) {
+				// skip bad entries ...
+			}
+			rootString = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_ROOT + "." + i, null); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		URL[] roots = (URL[]) rootList.toArray(new URL[0]);
+
+		// get primary flag
+		boolean primary = false;
+		String flag = loadAttribute(props, name + "." + CFG_FEATURE_ENTRY_PRIMARY, null); //$NON-NLS-1$
+		if (flag != null) {
+			if (flag.equals("true")) //$NON-NLS-1$
+				primary = true;
+		}
+		return createFeatureEntry(id, version, pluginIdentifier, pluginVersion, primary, application, roots);
+	}
+
+	private String[] loadListAttribute(Properties props, String name, String[] dflt) {
+		ArrayList list = new ArrayList();
+		String value = loadAttribute(props, name + ".0", null); //$NON-NLS-1$
+		if (value == null)
+			return dflt;
+
+		for (int i = 1; value != null; i++) {
+			loadListAttributeSegment(list, value);
+			value = loadAttribute(props, name + "." + i, null); //$NON-NLS-1$
+		}
+		return (String[]) list.toArray(new String[0]);
+	}
+
+	private void loadListAttributeSegment(ArrayList list, String value) {
+
+		if (value == null)
+			return;
+
+		StringTokenizer tokens = new StringTokenizer(value, ","); //$NON-NLS-1$
+		String token;
+		while (tokens.hasMoreTokens()) {
+			token = tokens.nextToken().trim();
+			if (!token.equals("")) //$NON-NLS-1$
+				list.add(token);
+		}
+		return;
+	}
+
+	private String loadAttribute(Properties props, String name, String dflt) {
+		String prop = props.getProperty(name);
+		if (prop == null)
+			return dflt;
+		else
+			return prop.trim();
+	}
+
+	private void loadInitializationAttributes() {
+
+		// look for the product initialization file relative to the install location
+		URL url = getInstallURL();
+
+		// load any initialization attributes. These are the default settings for
+		// key attributes (eg. default primary feature) supplied by the packaging team.
+		// They are always reloaded on startup to pick up any changes due to
+		// "native" updates.
+		Properties initProps = new Properties();
+		InputStream is = null;
+		try {
+			URL initURL = new URL(url, CONFIG_FILE_INIT);
+			is = initURL.openStream();
+			initProps.load(is);
+			if (DEBUG)
+				debug("Defaults from " + initURL.toExternalForm()); //$NON-NLS-1$
+		} catch (IOException e) {
+			return; // could not load default settings
+		} finally {
+			if (is != null) {
+				try {
+					is.close();
+				} catch (IOException e) {
+					// ignore ...
+				}
+			}
+		}
+
+		// use default settings if supplied
+		String initId = loadAttribute(initProps, INIT_DEFAULT_FEATURE_ID, null);
+		if (initId != null) {
+			String application = loadAttribute(initProps, INIT_DEFAULT_FEATURE_APPLICATION, null);
+			String initPluginId = loadAttribute(initProps, INIT_DEFAULT_PLUGIN_ID, null);
+			if (initPluginId == null)
+				initPluginId = initId;
+			IFeatureEntry fe = findConfiguredFeatureEntry(initId);
+
+			if (fe == null) {
+				// bug 26896 : setup optimistic reconciliation if the primary feature has changed or is new
+				cmdFirstUse = true;
+				// create entry if not exists
+				fe = createFeatureEntry(initId, null, initPluginId, null, true, application, null);
+			} else
+				// update existing entry with new info
+				fe = createFeatureEntry(initId, fe.getFeatureVersion(), fe.getFeaturePluginIdentifier(), fe.getFeaturePluginVersion(), fe.canBePrimary(), application, fe.getFeatureRootURLs());
+			configureFeatureEntry(fe);
+			defaultFeature = initId;
+			if (DEBUG) {
+				debug("    Default primary feature: " + defaultFeature); //$NON-NLS-1$
+				if (application != null)
+					debug("    Default application    : " + application); //$NON-NLS-1$
+			}
+		}
+	}
+
+	private HashMap getImport(URL entry, String id) {
+		if (id == null)
+			return null;
+		final String fId = id;
+
+		// parse out the import element attributes
+		Selector importSel = new Selector() {
+				// parse out import attributes
+	public boolean select(String element) {
+				if (element.startsWith("import")) //$NON-NLS-1$
+					return true;
+				else
+					return false;
+			}
+			public boolean select(String element, HashMap attributes) {
+				if (attributes == null)
+					return false;
+				String plugin = (String) attributes.get("plugin"); //$NON-NLS-1$
+				return fId.equals(plugin);
+			}
+		};
+		Parser p = new Parser(entry);
+		return p.getElement(importSel);
+	}
+
+	private BootDescriptor createPluginBootDescriptor(URL entry) {
+		if (entry == null)
+			return null;
+
+		// selector for plugin element
+		Selector pluginSel = new Selector() {
+			public boolean select(String element) {
+				if (element.startsWith("plugin")) //$NON-NLS-1$
+					return true;
+				else
+					return false;
+			}
+			public boolean select(String element, HashMap attributes) {
+				return true;
+			}
+		};
+
+		// selector for library elements
+		final ArrayList libs = new ArrayList();
+		Selector librarySel = new Selector() {
+			public boolean select(String element) {
+				if (element.startsWith("library")) //$NON-NLS-1$
+					return true;
+				else
+					return false;
+			}
+			public boolean select(String element, HashMap attributes) {
+				if (attributes == null)
+					return false;
+				String lib = (String) attributes.get("name"); //$NON-NLS-1$
+				if (lib != null)
+					libs.add(lib);
+				return false; // accumulate all library elements
+			}
+		};
+
+		// parse out descriptor information
+		Parser p = new Parser(entry);
+		String id = null;
+		String version = null;
+		HashMap attributes = p.getElement(pluginSel);
+		if (attributes != null) {
+			id = (String) attributes.get("id"); //$NON-NLS-1$
+			version = (String) attributes.get("version"); //$NON-NLS-1$
+		}
+		if (id == null)
+			id = ""; //$NON-NLS-1$
+		if (version == null)
+			version = "0.0.0"; //$NON-NLS-1$
+
+		p.getElement(librarySel);
+		String[] libraries = (String[]) libs.toArray(new String[0]);
+
+		String dir = entry.getFile();
+		int ix = dir.lastIndexOf("/"); //$NON-NLS-1$
+		dir = dir.substring(0, ix + 1);
+		URL dirURL = null;
+		try {
+			dirURL = new URL(entry.getProtocol(), entry.getHost(), entry.getPort(), dir);
+		} catch (MalformedURLException e) {
+			// continue ...
+		}
+
+		// return boot descriptor for the plugin
+		return new BootDescriptor(id, version, libraries, dirURL);
+	}
+
+	private URL getPluginPath(HashMap importElement) {
+		// return the plugin path element for the specified import element
+
+		if (importElement == null)
+			return null;
+
+		// determine which plugin we are looking for
+		VersionedIdentifier id;
+		String pid = (String) importElement.get("plugin"); //$NON-NLS-1$
+		String version = (String) importElement.get("version"); //$NON-NLS-1$
+		String match = (String) importElement.get("match"); //$NON-NLS-1$
+		if (pid == null)
+			return null; // bad <import> element
+		if (version == null)
+			id = new VersionedIdentifier(pid);
+		else {
+			id = new VersionedIdentifier(pid + "_" + version); //$NON-NLS-1$
+			if (match == null)
+				match = "compatible"; //$NON-NLS-1$
+		}
+
+		// search plugins on all configured sites
+		ISiteEntry[] sites = getConfiguredSites();
+		if (sites == null || sites.length == 0)
+			return null;
+
+		VersionedIdentifier savedVid = id; // initialize with baseline we are looking for
+		String savedEntry = null;
+		URL savedURL = null;
+		for (int j = 0; j < sites.length; j++) {
+			String[] plugins = sites[j].getPlugins();
+			for (int i = 0; plugins != null && i < plugins.length; i++) {
+				// look for best match.
+				// The entries are in the form <path>/<pluginDir>/plugin.xml
+				// look for -------------------------^
+				int ix = findEntrySeparator(plugins[i], 2); // second from end
+				if (ix == -1)
+					continue; // bad entry ... skip
+				String pluginDir = plugins[i].substring(ix + 1);
+				ix = pluginDir.indexOf("/"); //$NON-NLS-1$
+				if (ix != -1)
+					pluginDir = pluginDir.substring(0, ix);
+				if (pluginDir.equals("")) //$NON-NLS-1$
+					continue; // bad entry ... skip
+
+				// compare the candidate plugin using the matching rule
+				VersionedIdentifier vid = new VersionedIdentifier(pluginDir);
+				if (vid.equalIdentifiers(id)) {
+
+					// check if we have suffixed directory. If not (eg. self-hosting)
+					// we need to actually parse the plugin.xml to get its version
+					if (pluginDir.indexOf("_") == -1) { //$NON-NLS-1$
+						URL xmlURL = null;
+						try {
+							xmlURL = new URL(((SiteEntry) sites[j]).getResolvedURL(), plugins[i]);
+						} catch (MalformedURLException e) {
+							continue; // bad URL ... skip
+						}
+
+						// parse out the plugin element attributes
+						final String fpid = pid;
+						Selector versionSel = new Selector() {
+								// parse out plugin attributes
+	public boolean select(String element) {
+								if (element.startsWith("plugin")) //$NON-NLS-1$
+									return true;
+								else
+									return false;
+							}
+							public boolean select(String element, HashMap attributes) {
+								if (attributes == null)
+									return false;
+								String plugin = (String) attributes.get("id"); //$NON-NLS-1$
+								return fpid.equals(plugin);
+							}
+						};
+						Parser p = new Parser(xmlURL);
+						HashMap attributes = p.getElement(versionSel);
+						if (attributes == null)
+							continue; // bad xml ... skip
+						String pluginVersion;
+						if ((pluginVersion = (String) attributes.get("version")) == null) //$NON-NLS-1$
+							continue; // bad xml ... skip
+						pluginDir += "_" + pluginVersion; //$NON-NLS-1$
+						vid = new VersionedIdentifier(pluginDir);
+					}
+
+					// do the comparison
+					int result;
+					if ((result = vid.compareVersion(savedVid)) >= 0) {
+						if ("greaterOrEqual".equals(match)) { //$NON-NLS-1$
+							if (result > VersionedIdentifier.GREATER_THAN)
+								continue;
+						} else if ("compatible".equals(match)) { //$NON-NLS-1$
+							if (result > VersionedIdentifier.COMPATIBLE)
+								continue;
+						} else if ("equivalent".equals(match)) { //$NON-NLS-1$
+							if (result > VersionedIdentifier.EQUIVALENT)
+								continue;
+						} else if ("perfect".equals(match)) { //$NON-NLS-1$
+							if (result > VersionedIdentifier.EQUAL)
+								continue;
+						} else if (result > VersionedIdentifier.GREATER_THAN)
+							continue; // use the latest
+						savedVid = vid;
+						savedEntry = plugins[i];
+						savedURL = ((SiteEntry) sites[j]).getResolvedURL();
+					}
+				}
+			}
+		}
+
+		if (savedEntry == null)
+			return null;
+
+		try {
+			return new URL(savedURL, savedEntry);
+		} catch (MalformedURLException e) {
+			return null;
+		}
+	}
+
+	private void write(PrintWriter w) {
+		// write header
+		w.println("# " + (new Date()).toString()); //$NON-NLS-1$
+		writeAttribute(w, CFG_VERSION, VERSION);
+		if (transientConfig)
+			writeAttribute(w, CFG_TRANSIENT, "true"); //$NON-NLS-1$
+		w.println(""); //$NON-NLS-1$
+
+		// write global attributes
+		writeAttribute(w, CFG_STAMP, Long.toString(getChangeStamp()));
+		writeAttribute(w, CFG_FEATURE_STAMP, Long.toString(getFeaturesChangeStamp()));
+		writeAttribute(w, CFG_PLUGIN_STAMP, Long.toString(getPluginsChangeStamp()));
+
+		// write out bootstrap entries
+		String[] ids = getBootstrapPluginIdentifiers();
+		for (int i = 0; i < ids.length; i++) {
+			String location = (String) bootPlugins.get(ids[i]);
+			if (location != null)
+				writeAttribute(w, CFG_BOOT_PLUGIN + "." + ids[i], location); //$NON-NLS-1$
+		}
+
+		// write out feature entries
+		w.println(""); //$NON-NLS-1$
+		writeAttribute(w, CFG_FEATURE_ENTRY_DEFAULT, defaultFeature);
+		IFeatureEntry[] feats = getConfiguredFeatureEntries();
+		for (int i = 0; i < feats.length; i++) {
+			writeFeatureEntry(w, CFG_FEATURE_ENTRY + "." + Integer.toString(i), feats[i]); //$NON-NLS-1$
+		}
+
+		// write out site entries
+		SiteEntry[] list = (SiteEntry[]) sites.values().toArray(new SiteEntry[0]);
+		for (int i = 0; i < list.length; i++) {
+			writeSite(w, CFG_SITE + "." + Integer.toString(i), list[i]); //$NON-NLS-1$
+		}
+
+		// write end-of-file marker
+		writeAttribute(w, EOF, EOF);
+	}
+
+	private void writeSite(PrintWriter w, String id, SiteEntry entry) {
+
+		// write site separator
+		w.println(""); //$NON-NLS-1$
+
+		// write out site settings
+		writeAttribute(w, id + "." + CFG_URL, entry.getURL().toString()); //$NON-NLS-1$
+		writeAttribute(w, id + "." + CFG_STAMP, Long.toString(entry.getChangeStamp())); //$NON-NLS-1$
+		writeAttribute(w, id + "." + CFG_FEATURE_STAMP, Long.toString(entry.getFeaturesChangeStamp())); //$NON-NLS-1$
+		writeAttribute(w, id + "." + CFG_PLUGIN_STAMP, Long.toString(entry.getPluginsChangeStamp())); //$NON-NLS-1$
+		writeAttribute(w, id + "." + CFG_UPDATEABLE, entry.updateable ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		if (entry.linkFileName != null && !entry.linkFileName.trim().equals("")) //$NON-NLS-1$
+			writeAttribute(w, id + "." + CFG_LINK_FILE, entry.linkFileName.trim().replace(File.separatorChar, '/')); //$NON-NLS-1$
+
+		// write out site policy
+		int type = entry.getSitePolicy().getType();
+		String typeString = CFG_POLICY_TYPE_UNKNOWN;
+		try {
+			typeString = CFG_POLICY_TYPE[type];
+		} catch (IndexOutOfBoundsException e) {
+			// ignore bad attribute ...
+		}
+		writeAttribute(w, id + "." + CFG_POLICY, typeString); //$NON-NLS-1$
+		writeListAttribute(w, id + "." + CFG_LIST, entry.getSitePolicy().getList()); //$NON-NLS-1$
+	}
+
+	private void writeFeatureEntry(PrintWriter w, String id, IFeatureEntry entry) {
+
+		// write feature entry separator
+		w.println(""); //$NON-NLS-1$
+
+		// write out feature entry settings
+		writeAttribute(w, id + "." + CFG_FEATURE_ENTRY_ID, entry.getFeatureIdentifier()); //$NON-NLS-1$
+		if (entry.canBePrimary())
+			writeAttribute(w, id + "." + CFG_FEATURE_ENTRY_PRIMARY, "true"); //$NON-NLS-1$ //$NON-NLS-2$
+		writeAttribute(w, id + "." + CFG_FEATURE_ENTRY_VERSION, entry.getFeatureVersion()); //$NON-NLS-1$
+		if (entry.getFeatureVersion() != null && !entry.getFeatureVersion().equals(entry.getFeaturePluginVersion()))
+			writeAttribute(w, id + "." + CFG_FEATURE_ENTRY_PLUGIN_VERSION, entry.getFeaturePluginVersion()); //$NON-NLS-1$
+		if (entry.getFeatureIdentifier() != null && !entry.getFeatureIdentifier().equals(entry.getFeaturePluginIdentifier()))
+			writeAttribute(w, id + "." + CFG_FEATURE_ENTRY_PLUGIN_IDENTIFIER, entry.getFeaturePluginIdentifier()); //$NON-NLS-1$
+		writeAttribute(w, id + "." + CFG_FEATURE_ENTRY_APPLICATION, entry.getFeatureApplication()); //$NON-NLS-1$
+		URL[] roots = entry.getFeatureRootURLs();
+		for (int i = 0; i < roots.length; i++) {
+			// write our as individual attributes (is easier for Main.java to read)
+			writeAttribute(w, id + "." + CFG_FEATURE_ENTRY_ROOT + "." + i, roots[i].toExternalForm()); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+	private void writeListAttribute(PrintWriter w, String id, String[] list) {
+		if (list == null || list.length == 0)
+			return;
+
+		String value = ""; //$NON-NLS-1$
+		int listLen = 0;
+		int listIndex = 0;
+		for (int i = 0; i < list.length; i++) {
+			if (listLen != 0)
+				value += ","; //$NON-NLS-1$
+			else
+				value = ""; //$NON-NLS-1$
+			value += list[i];
+
+			if (++listLen >= CFG_LIST_LENGTH) {
+				writeAttribute(w, id + "." + Integer.toString(listIndex++), value); //$NON-NLS-1$
+				listLen = 0;
+			}
+		}
+		if (listLen != 0)
+			writeAttribute(w, id + "." + Integer.toString(listIndex), value); //$NON-NLS-1$
+	}
+
+	private void writeAttribute(PrintWriter w, String id, String value) {
+		if (value == null || value.trim().equals("")) //$NON-NLS-1$
+			return;
+		w.println(id + "=" + escapedValue(value)); //$NON-NLS-1$
+	}
+
+	private String escapedValue(String value) {
+		// if required, escape property values as \\uXXXX
+		StringBuffer buf = new StringBuffer(value.length() * 2); // assume expansion by less than factor of 2
+		for (int i = 0; i < value.length(); i++) {
+			char character = value.charAt(i);
+			if (character == '\\' || character == '\t' || character == '\r' || character == '\n' || character == '\f') {
+				// handle characters requiring leading \
+				buf.append('\\');
+				buf.append(character);
+			} else if ((character < 0x0020) || (character > 0x007e)) {
+				// handle characters outside base range (encoded)
+				buf.append('\\');
+				buf.append('u');
+				buf.append(HEX[(character >> 12) & 0xF]); // first nibble
+				buf.append(HEX[(character >> 8) & 0xF]); // second nibble
+				buf.append(HEX[(character >> 4) & 0xF]); // third nibble
+				buf.append(HEX[character & 0xF]); // fourth nibble
+			} else {
+				// handle base characters
+				buf.append(character);
+			}
+		}
+		return buf.toString();
+	}
+
+	private static String[] checkForFeatureChanges(String[] args, PlatformConfiguration cfg) {
+		String original = cfg.getApplicationIdentifierInternal();
+		String actual = cfg.getApplicationIdentifier();
+
+		if (original.equals(actual))
+			// base startup of specified application
+			return args;
+		else {
+			// Will run reconciler.
+			// Re-insert -application argument with original app and optionally
+			// force "first use" processing
+			int newArgCnt = cmdFirstUse ? 3 : 2;
+			String[] newArgs = new String[args.length + newArgCnt];
+			newArgs[0] = CMD_APPLICATION;
+			newArgs[1] = original;
+			if (cmdFirstUse)
+				newArgs[2] = CMD_FIRSTUSE;
+			System.arraycopy(args, 0, newArgs, newArgCnt, args.length);
+			if (DEBUG)
+				debug("triggering reconciliation ..."); //$NON-NLS-1$
+			return newArgs;
+		}
+	}
+
+	private static String[] checkForNewUpdates(IPlatformConfiguration cfg, String[] args) {
+		try {
+			URL markerURL = new URL(cfg.getConfigurationLocation(), CHANGES_MARKER);
+			File marker = new File(markerURL.getFile());
+			if (!marker.exists())
+				return args;
+
+			// indicate -newUpdates
+			marker.delete();
+			String[] newArgs = new String[args.length + 1];
+			newArgs[0] = CMD_NEW_UPDATES;
+			System.arraycopy(args, 0, newArgs, 1, args.length);
+			return newArgs;
+		} catch (MalformedURLException e) {
+			return args;
+		}
+	}
+
+	private static String[] processCommandLine(String[] args) throws Exception {
+		int[] configArgs = new int[100];
+		configArgs[0] = -1; // need to initialize the first element to something that could not be an index.
+		int configArgIndex = 0;
+		for (int i = 0; i < args.length; i++) {
+			boolean found = false;
+
+			// check for args without parameters (i.e., a flag arg)
+
+			// look for forced "first use" processing (triggered by stale
+			// bootstrap information)
+			if (args[i].equalsIgnoreCase(CMD_FIRSTUSE)) {
+				cmdFirstUse = true;
+				found = true;
+			}
+
+			// look for the update flag
+			if (args[i].equalsIgnoreCase(CMD_UPDATE)) {
+				cmdUpdate = true;
+				found = true;
+			}
+
+			// look for the no-update flag
+			if (args[i].equalsIgnoreCase(CMD_NO_UPDATE)) {
+				cmdNoUpdate = true;
+				found = true;
+			}
+
+			// look for the initialization flag
+			if (args[i].equalsIgnoreCase(CMD_INITIALIZE)) {
+				cmdInitialize = true;
+				continue; // do not remove from command line
+			}
+
+			// look for the development mode flag ... triggers no-update
+			if (args[i].equalsIgnoreCase(CMD_DEV)) {
+				cmdDev = true;
+				continue; // do not remove from command line
+			}
+
+			if (found) {
+				configArgs[configArgIndex++] = i;
+				continue;
+			}
+
+			// check for args with parameters. If we are at the last argument or if the next one
+			// has a '-' as the first character, then we can't have an arg with a parm so continue.
+
+			if (i == args.length - 1 || args[i + 1].startsWith("-")) { //$NON-NLS-1$
+				continue;
+			}
+
+			String arg = args[++i];
+
+			// look for the platform configuration to use.
+			if (args[i - 1].equalsIgnoreCase(CMD_CONFIGURATION)) {
+				found = true;
+				cmdConfiguration = arg;
+			}
+
+			// look for the feature to use for customization.
+			if (args[i - 1].equalsIgnoreCase(CMD_FEATURE)) {
+				found = true;
+				cmdFeature = arg;
+			}
+
+			// look for the application to run.  Only use the value from the
+			// command line if the application identifier was not explicitly
+			// passed on BootLoader.run(...) invocation.
+			if (args[i - 1].equalsIgnoreCase(CMD_APPLICATION)) {
+				found = true;
+				if (cmdApplication == null)
+					cmdApplication = arg;
+			}
+
+			// R1.0 compatibility
+			// look for the plugins location to use.  Only use the value from the
+			// command line if the plugins location was not explicitly passed on
+			// BootLoader.run(...) or BootLoader.startup(...) invocation.
+			if (args[i - 1].equalsIgnoreCase(CMD_PLUGINS)) {
+				found = true;
+				// if the arg can be made into a URL use it. Otherwise assume that
+				// it is a file path so make a file URL.
+				try {
+					if (cmdPlugins == null)
+						cmdPlugins = new URL(arg);
+				} catch (MalformedURLException e) {
+					try {
+						cmdPlugins = new URL("file:" + arg.replace(File.separatorChar, '/')); //$NON-NLS-1$
+					} catch (MalformedURLException e2) {
+						throw e; // rethrow original exception
+					}
+				}
+			}
+
+			// done checking for args.  Remember where an arg was found
+			if (found) {
+				configArgs[configArgIndex++] = i - 1;
+				configArgs[configArgIndex++] = i;
+			}
+		}
+
+		// remove all the arguments consumed by this argument parsing
+		if (configArgIndex == 0)
+			return args;
+		String[] passThruArgs = new String[args.length - configArgIndex];
+		configArgIndex = 0;
+		int j = 0;
+		for (int i = 0; i < args.length; i++) {
+			if (i == configArgs[configArgIndex])
+				configArgIndex++;
+			else
+				passThruArgs[j++] = args[i];
+		}
+		return passThruArgs;
+	}
+
+	private static int findEntrySeparator(String pathEntry, int cnt) {
+		for (int i = pathEntry.length() - 1; i >= 0; i--) {
+			if (pathEntry.charAt(i) == '/') {
+				if (--cnt == 0)
+					return i;
+			}
+		}
+		return -1;
+	}
+
+	private static String[] stringListToArray(String prop, String separator) {
+		if (prop == null || prop.trim().equals("")) //$NON-NLS-1$
+			return new String[0];
+		ArrayList list = new ArrayList();
+		StringTokenizer tokens = new StringTokenizer(prop, separator);
+		while (tokens.hasMoreTokens()) {
+			String token = tokens.nextToken().trim();
+			if (!token.equals("")) //$NON-NLS-1$
+				list.add(token);
+		}
+		return list.isEmpty() ? new String[0] : (String[]) list.toArray(new String[0]);
+	}
+
+	private static boolean supportsDetection(URL url) {
+		String protocol = url.getProtocol();
+		if (protocol.equals("file")) //$NON-NLS-1$
+			return true;
+		else if (protocol.equals(PlatformURLHandler.PROTOCOL)) {
+			URL resolved = null;
+			try {
+				resolved = resolvePlatformURL(url); // 19536
+			} catch (IOException e) {
+				return false; // we tried but failed to resolve the platform URL
+			}
+			return resolved.getProtocol().equals("file"); //$NON-NLS-1$
+		} else
+			return false;
+	}
+
+	private static void verifyPath(URL url) {
+		String protocol = url.getProtocol();
+		String path = null;
+		if (protocol.equals("file")) //$NON-NLS-1$
+			path = url.getFile();
+		else if (protocol.equals(PlatformURLHandler.PROTOCOL)) {
+			URL resolved = null;
+			try {
+				resolved = resolvePlatformURL(url); // 19536
+				if (resolved.getProtocol().equals("file")) //$NON-NLS-1$
+					path = resolved.getFile();
+			} catch (IOException e) {
+				// continue ...
+			}
+		}
+
+		if (path != null) {
+			File dir = new File(path).getParentFile();
+			if (dir != null)
+				dir.mkdirs();
+		}
+	}
+
+	private static URL resolvePlatformURL(URL url) throws IOException {
+		// 19536
+		if (url.getProtocol().equals(PlatformURLHandler.PROTOCOL)) {
+			URLConnection connection = url.openConnection();
+			if (connection instanceof PlatformURLConnection) {
+				url = ((PlatformURLConnection) connection).getResolvedURL();
+			} else {
+				//				connection = new PlatformURLBaseConnection(url);
+				//				url = ((PlatformURLConnection)connection).getResolvedURL();
+				url = getInstallURL();
+			}
+		}
+		return url;
+	}
+
+	private static void debug(String s) {
+		System.out.println("PlatformConfig: " + s); //$NON-NLS-1$
+	}
+
+	private void resetUpdateManagerState(URL url) throws IOException {
+		// [20111]
+		if (!supportsDetection(url))
+			return; // can't do ...
+
+		// find directory where the platform configuration file is	
+		URL resolved = resolvePlatformURL(url);
+		File initCfg = new File(resolved.getFile().replace('/', File.separatorChar));
+		File initDir = initCfg.getParentFile();
+
+		// Find the Update Manager State directory
+		if (initDir == null || !initDir.exists() || !initDir.isDirectory())
+			return;
+		String temp = initCfg.getName() + ".metadata"; //$NON-NLS-1$
+		File UMDir = new File(initDir, temp + '/');
+
+		// Attempt to rename it
+		if (UMDir == null || !UMDir.exists() || !UMDir.isDirectory())
+			return;
+		Date now = new Date();
+		boolean renamed = UMDir.renameTo(new File(initDir, temp + now.getTime() + '/'));
+
+		if (!renamed)
+			resetInitializationLocation(UMDir);
+	}
+
+	private static URL getInstallURL() {
+		return installURL;
+	}
+
+	private URL getDefaultStateLocation() throws IOException {
+		// 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 installURL = getInstallURL();
+		File installDir = new File(installURL.getFile());
+
+		if ("file".equals(installURL.getProtocol()) && installDir.canWrite()) { //$NON-NLS-1$
+			if (DEBUG)
+				debug("Using the installation directory."); //$NON-NLS-1$
+			return installURL;
+		} else {
+			if (DEBUG)
+				debug("Using the user.home location."); //$NON-NLS-1$
+			String appName = "." + ECLIPSE; //$NON-NLS-1$
+			File eclipseProduct = new File(installDir, PRODUCT_SITE_MARKER);
+			if (eclipseProduct.exists()) {
+				Properties props = new Properties();
+				props.load(new FileInputStream(eclipseProduct));
+				String appId = props.getProperty(PRODUCT_SITE_ID);
+				if (appId == null || appId.trim().length() == 0)
+					appId = ECLIPSE;
+				String appVersion = props.getProperty(PRODUCT_SITE_VERSION);
+				if (appVersion == null || appVersion.trim().length() == 0)
+					appVersion = ""; //$NON-NLS-1$
+				appName += File.separator + appId + "_" + appVersion; //$NON-NLS-1$
+			}
+
+			String userHome = System.getProperty("user.home"); //$NON-NLS-1$
+			File configDir = new File(userHome, appName);
+			configDir.mkdirs();
+			return configDir.toURL();
+		}
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/PlatformConfigurationFactory.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/PlatformConfigurationFactory.java
new file mode 100644
index 0000000..be9bc34
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/PlatformConfigurationFactory.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.io.IOException;
+import java.net.URL;
+
+
+public class PlatformConfigurationFactory implements IPlatformConfigurationFactory {
+	public IPlatformConfiguration getCurrentPlatformConfiguration() {
+		return PlatformConfiguration.getCurrent();
+	}
+	public IPlatformConfiguration getPlatformConfiguration(URL url) throws IOException {
+		return new PlatformConfiguration(url);
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/Policy.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/Policy.java
new file mode 100644
index 0000000..58bb52c
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/Policy.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+public class Policy {
+	private static String bundleName = "org.eclipse.update.configurator.messages"; //$NON-NLS-1$
+	private static ResourceBundle bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
+
+	/**
+	 * Lookup the message with the given ID in this catalog 
+	 */
+	public static String bind(String id) {
+		return bind(id, (String[]) null);
+	}
+	/**
+	 * Lookup the message with the given ID in this catalog and bind its
+	 * substitution locations with the given string.
+	 */
+	public static String bind(String id, String binding) {
+		return bind(id, new String[] { binding });
+	}
+	/**
+	 * Lookup the message with the given ID in this catalog and bind its
+	 * substitution locations with the given strings.
+	 */
+	public static String bind(String id, String binding1, String binding2) {
+		return bind(id, new String[] { binding1, binding2 });
+	}
+
+	/**
+	 * Lookup the message with the given ID in this catalog and bind its
+	 * substitution locations with the given string values.
+	 */
+	public static String bind(String id, String[] bindings) {
+		if (id == null)
+			return "No message available"; //$NON-NLS-1$
+		String message = null;
+		try {
+			message = bundle.getString(id);
+		} catch (MissingResourceException e) {
+			// If we got an exception looking for the message, fail gracefully by just returning
+			// the id we were looking for.  In most cases this is semi-informative so is not too bad.
+			return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		if (bindings == null)
+			return message;
+		return MessageFormat.format(message, bindings);
+	}
+	/**
+	 * Print a debug message to the console. If the given boolean is <code>true</code> then
+	 * pre-pend the message with the current date.
+	 */
+	public static void debug(boolean includeDate, String message) {
+		if (includeDate)
+			message = new Date(System.currentTimeMillis()).toString() + " - " + message; //$NON-NLS-1$
+		System.out.println(message);
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/Utils.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/Utils.java
new file mode 100644
index 0000000..6701051
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/Utils.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.core.internal.boot.PlatformURLBaseConnection;
+
+public class Utils {
+	private static final String PLUGIN_PATH = ".plugin-path"; //$NON-NLS-1$
+
+	/*
+	 * This method is retained for R1.0 compatibility because it is defined as API.
+	 * It's function matches the API description (returns <code>null</code> when
+	 * argument URL is <code>null</code> or cannot be read).
+	 */
+	public static URL[] getPluginPath(URL pluginPathLocation /*R1.0 compatibility*/
+	) {
+		InputStream input = null;
+		// first try and see if the given plugin path location exists.
+		if (pluginPathLocation == null)
+			return null;
+		try {
+			input = pluginPathLocation.openStream();
+		} catch (IOException e) {
+			//fall through
+		}
+
+		// if the given path was null or did not exist, look for a plugin path
+		// definition in the install location.
+		if (input == null)
+			try {
+				URL url = new URL(PlatformURLBaseConnection.PLATFORM_URL_STRING + PLUGIN_PATH);
+				input = url.openStream();
+			} catch (MalformedURLException e) {
+				//fall through
+			} catch (IOException e) {
+				//fall through
+			}
+
+		// nothing was found at the supplied location or in the install location
+		if (input == null)
+			return null;
+		// if we found a plugin path definition somewhere so read it and close the location.
+		URL[] result = null;
+		try {
+			try {
+				result = readPluginPath(input);
+			} finally {
+				input.close();
+			}
+		} catch (IOException e) {
+			//let it return null on failure to read
+		}
+		return result;
+	}
+
+	private static URL[] readPluginPath(InputStream input) {
+		Properties ini = new Properties();
+		try {
+			ini.load(input);
+		} catch (IOException e) {
+			return null;
+		}
+		Vector result = new Vector(5);
+		for (Enumeration groups = ini.propertyNames(); groups.hasMoreElements();) {
+			String group = (String) groups.nextElement();
+			for (StringTokenizer entries = new StringTokenizer(ini.getProperty(group), ";"); entries.hasMoreElements();) { //$NON-NLS-1$
+				String entry = (String) entries.nextElement();
+				if (!entry.equals("")) //$NON-NLS-1$
+					try {
+						result.addElement(new URL(entry));
+					} catch (MalformedURLException e) {
+						//intentionally ignore bad URLs
+						System.err.println(Policy.bind("ignore.plugin", entry)); //$NON-NLS-1$
+					}
+			}
+		}
+		return (URL[]) result.toArray(new URL[result.size()]);
+	}
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/messages.properties b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/messages.properties
new file mode 100644
index 0000000..8dc04df
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/messages.properties
@@ -0,0 +1,43 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+### Boot plugin message catalog
+
+ok = OK
+
+### URL
+url.badVariant=Unsupported \"platform:\" protocol variation {0}
+url.invalidURL=Invalid "platform:" URL {0}
+url.createConnection=Unable to create connection {0}
+url.noaccess=Unable to access URL as local {0}.
+
+### Platform Configuration
+cfig.inUse=\nConfiguration file \"{0}\" is in use by another instance of the platform, \n\
+	or there was a failure in deleting the old lock file.  If no other platform instances are running, \n\
+	delete file \"{1}\" and try starting the platform again.
+cfig.failCreateLock=Failed to create lock for configuration file \"{0}\"
+cfig.badUrlArg=Bad -configuration argument \"{0}\"
+cfig.unableToLoad.incomplete=Unable to load {0}
+cfig.unableToLoad.noURL=Configuration file location not specified
+cfig.unableToSave.noURL=Configuration file save location not specified
+cfig.unableToSave=Unable to save configuration file \"{0}\"
+cfig.badVersion=Unsupported configuration version \"{0}\"
+
+platform.running=The Platform is already running.
+platform.mustNotBeRunning=The Platform must not be running.
+platform.notRunning=The Platform is not running.
+
+ignore.plugin=Ignoring invalid plug-in location: {0}.
+application.notFound=Application not found: {0}.
+error.fatal=Fatal Error: Unable to determine platform installation URL {0}.
+error.boot=Fatal Error: Unable to locate boot.xml file for executing org.eclipse.core.boot.
+error.runtime=Fatal Error: Unable to locate matching org.eclipse.core.runtime plug-in.
+error.xerces=Fatal Error: Unable to locate matching org.apache.xerces plug-in.
+error.badNL=Bad value: \"{0}\" for NL. Using system default.
\ No newline at end of file
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/IPluginInfo.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/IPluginInfo.java
new file mode 100644
index 0000000..26170e5
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/IPluginInfo.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator.migration;
+
+import java.util.Map;
+import java.util.Set;
+
+public interface IPluginInfo {
+	public Map getLibraries();
+	public String[] getLibrariesName();
+	public String[] getRequires();
+	public String getMasterId();
+	public String getMasterVersion();
+	public String getPluginClass();
+	public String getUniqueId();
+	public String getVersion();
+	public boolean isFragment();
+	public Set getPackageFilters();
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/PluginConverter.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/PluginConverter.java
new file mode 100644
index 0000000..d009370
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/PluginConverter.java
@@ -0,0 +1,435 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator.migration;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import org.eclipse.update.configurator.ConfigurationActivator;
+import org.eclipse.update.configurator.IPluginConverter;
+import org.osgi.framework.Constants;
+import org.xml.sax.SAXException;
+
+public class PluginConverter implements IPluginConverter {
+	private static final String LEGACY = "Legacy"; //$NON-NLS-1$
+	private static final String PLUGIN = "Plugin-Class"; //$NON-NLS-1$
+
+	protected String devPathSpec;
+	private IPluginInfo pluginInfo;
+	private File bundleManifestLocation;
+	private File pluginLocation;
+	private PrintWriter out;
+
+	private static final String[] ARCH_LIST = { org.eclipse.osgi.service.environment.Constants.ARCH_PA_RISC, org.eclipse.osgi.service.environment.Constants.ARCH_PPC, org.eclipse.osgi.service.environment.Constants.ARCH_SPARC, org.eclipse.osgi.service.environment.Constants.ARCH_X86 };
+	private static final String[] OS_LIST =
+		{
+			org.eclipse.osgi.service.environment.Constants.OS_AIX,
+			org.eclipse.osgi.service.environment.Constants.OS_HPUX,
+			org.eclipse.osgi.service.environment.Constants.OS_LINUX,
+			org.eclipse.osgi.service.environment.Constants.OS_MACOSX,
+			org.eclipse.osgi.service.environment.Constants.OS_QNX,
+			org.eclipse.osgi.service.environment.Constants.OS_SOLARIS,
+			org.eclipse.osgi.service.environment.Constants.OS_WIN32 };
+	private static final String[] WS_LIST =
+		{ org.eclipse.osgi.service.environment.Constants.WS_CARBON, org.eclipse.osgi.service.environment.Constants.WS_GTK, org.eclipse.osgi.service.environment.Constants.WS_MOTIF, org.eclipse.osgi.service.environment.Constants.WS_PHOTON, org.eclipse.osgi.service.environment.Constants.WS_WIN32 };
+
+	public PluginConverter() {
+		super();
+		devPathSpec = System.getProperty("osgi.dev");
+	}
+
+	public void convertManifest(IPluginInfo pluginInfo, File pluginLocation, File bundleManifestLocation) {
+		this.pluginInfo = pluginInfo;
+		this.pluginLocation = pluginLocation;
+		this.bundleManifestLocation = bundleManifestLocation;
+		generate();
+	}
+
+	public boolean convertManifest(File pluginLocation, File bundleManifestLocation) {
+		/* parse the plugin manifest to find out:
+		 * - the plug-in unique identifier
+		 * - the plug-in version
+		 * - runtime/libraries entries
+		 * - the plug-in class
+		 * - the master plugin (for a fragment)
+		 */
+		this.pluginLocation = pluginLocation;
+		this.bundleManifestLocation = bundleManifestLocation;
+		File pluginManifestLocation = new File(pluginLocation, "plugin.xml");
+		if (!pluginManifestLocation.isFile()) {
+			pluginManifestLocation = new File(pluginLocation, "fragment.xml");
+			if (!pluginManifestLocation.isFile())
+				// location does not contain a plugin manifest
+				return false;
+		}
+		try {
+			pluginInfo = new PluginParser().parse(pluginManifestLocation.toString());
+			generate();
+		} catch (IOException e) {
+			//TODO: what to do here? 
+			e.printStackTrace();
+			return false;
+		} catch (SAXException e) {
+			//TODO: what to do here?		
+			e.printStackTrace();
+			return false;
+		}
+		return true;
+	}
+
+	protected void generate() {
+		openFile();
+		generateHeaders();
+		generateClasspath();
+		generateLegacy();
+		generateActivator();
+		generatePluginClass();
+		generateProvidePackage();
+		generateImports();
+		generateRequireBundle();
+		closeFile();
+		if (ConfigurationActivator.DEBUG_CONVERTER)
+			System.out.println("Generated manifest on-the-fly at: " + bundleManifestLocation);
+	}
+
+	private void generateRequireBundle() {
+		String[] requiredBundles = pluginInfo.getRequires();
+		if (requiredBundles == null && !pluginInfo.getUniqueId().equals("org.eclipse.core.runtime")) // to avoid cycles
+			requiredBundles = new String[] { "org.eclipse.core.runtime" };
+
+		writeEntry(Constants.REQUIRE_BUNDLE, requiredBundles);
+	}
+
+	private void generateLegacy() {
+		writeEntry(LEGACY, "true");
+	}
+
+	private void generateImports() {
+		// TODO We should not need DynamicImport-Package or Import-Package
+		// writeEntry(Constants.DYNAMICIMPORT_PACKAGE, "*");
+	}
+
+	private void openFile() {
+		try {
+			bundleManifestLocation.getParentFile().mkdirs();
+			bundleManifestLocation.createNewFile();
+		} catch (IOException e) {
+			System.err.println("error creating directory writing manifest for " + pluginInfo.getUniqueId());
+			return;
+		}
+		BufferedOutputStream outputFile = null;
+		try {
+			outputFile = new BufferedOutputStream(new FileOutputStream(bundleManifestLocation));
+		} catch (FileNotFoundException e) {
+			System.err.println("error writing manifest for " + pluginInfo.getUniqueId());
+			return;
+		}
+		out = new PrintWriter(outputFile);
+		// so it is easy to tell which ones are generated
+		out.println("Generated: true");
+	}
+
+	private void writeEntry(String key, Collection value) {
+		if (value == null || value.size() == 0)
+			return;
+		if (value.size() == 1) {
+			out.println(key + ": " + value.iterator().next());
+			return;
+		}
+		key = key + ": ";
+		out.println(key);
+		out.print(' ');
+		boolean first = true;
+		for (Iterator i = value.iterator(); i.hasNext();) {
+			if (first)
+				first = false;
+			else {
+				out.println(',');
+				out.print(' ');
+			}
+			out.print(i.next());
+		}
+		out.println();
+	}
+
+	private void writeEntry(String key, String[] value) {
+		if (value == null || value.length == 0)
+			return;
+		if (value.length == 1) {
+			out.println(key + ": " + value[0]);
+			return;
+		}
+		key = key + ": ";
+		out.println(key);
+		out.print(' ');
+		boolean first = true;
+		for (int i = 0; i < value.length; i++) {
+			if (first)
+				first = false;
+			else {
+				out.println(',');
+				out.print(' ');
+			}
+			out.print(value[i]);
+		}
+		out.println();
+	}
+
+	private void writeEntry(String key, String value) {
+		if (value != null && value.length() > 0)
+			out.println(key + ": " + value);
+	}
+
+	private void closeFile() {
+		out.close();
+	}
+
+	private void generateHeaders() {
+		writeEntry(Constants.BUNDLE_NAME, pluginInfo.getUniqueId());
+		writeEntry(Constants.BUNDLE_VERSION, pluginInfo.getVersion());
+		writeEntry(Constants.BUNDLE_GLOBALNAME, pluginInfo.getUniqueId());
+	}
+	private void generateProvidePackage() {
+		StringBuffer providePackage = new StringBuffer();
+		Set exports = getExports();
+		if (exports != null) {
+			Iterator iter = exports.iterator();
+			boolean firstPkg = true;
+			while (iter.hasNext()) {
+				String pkg = (String) iter.next();
+				if (firstPkg) {
+					providePackage.append("\n ");
+					firstPkg = false;
+				} else {
+					providePackage.append(",\n ");
+				}
+				providePackage.append(pkg);
+			}
+			writeEntry(Constants.PROVIDE_PACKAGE, providePackage.toString());
+		}
+
+		if (pluginInfo.isFragment()) {
+			StringBuffer hostBundle = new StringBuffer();
+
+			hostBundle.append(pluginInfo.getMasterId()).append("; ");
+			hostBundle.append(Constants.BUNDLE_VERSION_ATTRIBUTE).append("=");
+			hostBundle.append(pluginInfo.getMasterVersion());
+
+			writeEntry(Constants.HOST_BUNDLE, hostBundle.toString());
+		}
+	}
+
+	private ArrayList getLibrariesExpandingVariables(String libraryPath, boolean filter) {
+		String var = hasPrefix(libraryPath);
+		if (var == null) {
+			ArrayList returnValue = new ArrayList(1);
+			returnValue.add(libraryPath);
+			return returnValue;
+		}
+		if (var.equals("ws")) {
+			return findWSJars(pluginLocation, libraryPath, filter);
+		}
+		if (var.equals("os")) {
+			return findOSJars(pluginLocation, libraryPath, filter);
+		}
+		return new ArrayList(0);
+	}
+
+	private void generateClasspath() {
+		String[] libraries = pluginInfo.getLibrariesName();
+		ArrayList expandedPath = new ArrayList();
+		for (int i = 0; i < libraries.length; i++) {
+			expandedPath.addAll(getLibrariesExpandingVariables(libraries[i], true));
+		}
+		writeEntry(Constants.BUNDLE_CLASSPATH, expandedPath);
+	}
+
+	private ArrayList findWSJars(File pluginRoot, String path, boolean filter) {
+		path = path.substring(4);
+		ArrayList found = new ArrayList(0);
+		for (int i = 0; i < WS_LIST.length; i++) {
+			String searchedPath = "ws/" + WS_LIST[i] + path;
+			if (new File(pluginRoot, searchedPath).exists()) {
+				found.add(searchedPath + (filter ? ";(ws=" + WS_LIST[i] + ")" : ""));
+			}
+		}
+		return found;
+	}
+
+	private ArrayList findOSJars(File pluginRoot, String path, boolean filter) {
+		path = path.substring(4);
+		ArrayList found = new ArrayList(0);
+		for (int i = 0; i < OS_LIST.length; i++) {
+			//look for os/osname/path
+			String searchedPath = "os/" + OS_LIST[i] + "/" + path;
+			if (new File(pluginRoot, searchedPath).exists())
+				found.add(searchedPath + (filter ? ";(os=" + WS_LIST[i] + ")" : ""));
+
+			//look for os/osname/archname/path
+			for (int j = 0; j < ARCH_LIST.length; j++) {
+				searchedPath = "os/" + OS_LIST[i] + "/" + ARCH_LIST[j] + "/" + path;
+				if (new File(pluginRoot, searchedPath).exists()) {
+					found.add(searchedPath + (filter ? ";(& (os=" + WS_LIST[i] + ") (arch=" + ARCH_LIST[j] + ")" : ""));
+				}
+			}
+		}
+		return found;
+	}
+	//return a String representing the string found between the $s
+	private String hasPrefix(String libPath) {
+		if (libPath.startsWith("$ws$"))
+			return "ws";
+		if (libPath.startsWith("$os$"))
+			return "os";
+		if (libPath.startsWith("$nl$"))
+			return "nl";
+		return null;
+	}
+
+	private void generateActivator() {
+		if (!pluginInfo.isFragment())
+			writeEntry(Constants.BUNDLE_ACTIVATOR, "org.eclipse.core.runtime.compatibility.PluginActivator");
+	}
+
+	private void generatePluginClass() {
+		writeEntry(PLUGIN, pluginInfo.getPluginClass());
+	}
+
+	private Set filterExport(Collection exportToFilter, Collection filter) {
+		if (filter == null || filter.contains("*"))
+			return (Set) exportToFilter;
+
+		Set filteredExport = new HashSet(exportToFilter.size());
+		for (Iterator iter = exportToFilter.iterator(); iter.hasNext();) {
+			String anExport = (String) iter.next();
+
+			for (Iterator iter2 = filter.iterator(); iter2.hasNext();) {
+				String aFilter = (String) iter2.next();
+				if (anExport.startsWith(aFilter)) {
+					filteredExport.add(anExport);
+				}
+			}
+		}
+		return filteredExport;
+	}
+
+	private Set getExportsFromJAR(File jarFile) {
+		Set names = new HashSet();
+		JarFile file = null;
+		try {
+			file = new JarFile(jarFile);
+		} catch (IOException e) {
+			System.err.println("Ignore " + jarFile);
+			return names;
+		}
+
+		//Run through the entries
+		for (Enumeration enum = file.entries(); enum.hasMoreElements();) {
+			JarEntry entry = (JarEntry) enum.nextElement();
+			String name = entry.getName();
+
+			int lastSlash = name.lastIndexOf("/");
+			//Ignore folders that do not contain files
+			if (lastSlash != -1 && lastSlash != name.length() - 1) {
+				if (name.lastIndexOf(' ') == -1 && !name.equalsIgnoreCase("meta-inf/manifest.mf"))
+					names.add(name.substring(0, lastSlash).replace('/', '.'));
+			}
+		}
+		return names;
+	}
+
+	private Set getExportsFromDir(File location) {
+		return getExportsFromDir(location, "");
+	}
+
+	private Set getExportsFromDir(File location, String packageName) {
+		String prefix = (packageName.length() > 0) ? (packageName + '.') : "";
+		File[] files = location.listFiles();
+		Set exportedPaths = new HashSet();
+		boolean containsFile = false;
+		for (int i = 0; i < files.length; i++) {
+			if (files[i].isDirectory())
+				exportedPaths.addAll(getExportsFromDir(files[i], prefix + files[i].getName()));
+			else
+				containsFile = true;
+		}
+		if (containsFile && packageName.length() > 0)
+			exportedPaths.add(packageName);
+		return exportedPaths;
+	}
+
+	private Set getExports() {
+		Map libs = pluginInfo.getLibraries();
+		if (libs == null)
+			return null;
+
+		// Based on similar code from EclipseStarter
+		// Check the osgi.dev property to see if dev classpath entries have been defined.
+		//		String osgiDev = System.getProperty("osgi.dev");
+		String[] devClassPath = null;
+		if (devPathSpec != null) {
+			// Add each dev classpath entry
+			Vector tokens = new Vector(6);
+			StringTokenizer t = new StringTokenizer(devPathSpec, ",");
+			while (t.hasMoreTokens()) {
+				String token = t.nextToken();
+				if (!token.equals("")) {
+					tokens.addElement(token);
+				}
+			}
+			devClassPath = new String[tokens.size()];
+			tokens.toArray(devClassPath);
+		}
+
+		// add the dev. time classpath entries
+		List starExport = new ArrayList(1);
+		starExport.add("*");
+		if (devClassPath != null) {
+			for (int i = 0; i < devClassPath.length; i++) {
+				libs.put(devClassPath[i], starExport);
+			}
+		}
+		Set result = new HashSet(7);
+		Set libEntries = libs.entrySet();
+		for (Iterator iter = libEntries.iterator(); iter.hasNext();) {
+			Map.Entry element = (Map.Entry) iter.next();
+			List filter = (List) element.getValue();
+			if (filter.size() == 0) //If the library is not exported, then ignore it
+				continue;
+
+			File libraryLocation = new File(pluginLocation, (String) element.getKey());
+			Set exports = null;
+			if (libraryLocation.exists()) {
+				if (libraryLocation.isFile())
+					exports = filterExport(getExportsFromJAR(libraryLocation), filter); //TODO Need to handle $xx$ variables
+				else if (libraryLocation.isDirectory())
+					exports = filterExport(getExportsFromDir(libraryLocation), filter);
+			} else {
+				ArrayList expandedLibs = getLibrariesExpandingVariables((String) element.getKey(), false);
+				exports = new HashSet();
+				for (Iterator iterator = expandedLibs.iterator(); iterator.hasNext();) {
+					String libName = (String) iterator.next();
+					File libFile = new File(pluginLocation, libName);
+					if (libFile.isFile()) {
+						exports.addAll(filterExport(getExportsFromJAR(libFile), filter));
+					}
+				}
+			}
+
+			if (exports != null) {
+				result.addAll(exports);
+			}
+		}
+		return result;
+	}
+
+}
diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/PluginParser.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/PluginParser.java
new file mode 100644
index 0000000..8fb8a89
--- /dev/null
+++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/configurator/migration/PluginParser.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.update.configurator.migration;
+
+import java.io.IOException;
+import java.util.*;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import org.eclipse.update.configurator.ConfigurationActivator;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class PluginParser extends DefaultHandler {
+	/**
+	 * Manifest schema version from "eclipse" processing directive, or
+	 * <code>null</code> if none.
+	 * @since 3.0
+	 */
+	private String schemaVersion = null;
+	private PluginInfo manifestInfo = new PluginInfo();
+	private List exportStatement;
+
+	// model parser
+	private ServiceReference parserReference;
+
+	public PluginParser() {
+		super();
+	}
+
+	public PluginInfo parse(String fileLocation) throws IOException, SAXException {
+		SAXParserFactory factory = acquireXMLParsing();
+		if (factory == null)
+			return null;
+		try {
+			factory.setNamespaceAware(true);
+			factory.setFeature("http://xml.org/sax/features/string-interning", true); //$NON-NLS-1$
+			factory.setValidating(false);
+			factory.newSAXParser().parse(fileLocation, this);
+		} catch (ParserConfigurationException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} finally {
+			releaseXMLParsing();
+		}
+		return manifestInfo;
+	}
+
+	public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException {
+		if (elementName.equals("plugin") || elementName.equals("fragment")) {
+			manifestInfo.pluginId = attributes.getValue("", "id");
+			manifestInfo.version = attributes.getValue("", "version");
+			manifestInfo.pluginClass = attributes.getValue("", "class");
+			manifestInfo.schemaVersion = schemaVersion;
+			if (elementName.equals("fragment")) {
+				manifestInfo.masterPluginId = attributes.getValue("", "plugin-id");
+				manifestInfo.masterVersion = attributes.getValue("", "plugin-version");
+			}
+		} else if (elementName.equals("library")) {
+			if (manifestInfo.libraries == null)
+				manifestInfo.libraries = new HashMap();
+			exportStatement = new ArrayList();
+			manifestInfo.libraries.put(attributes.getValue("", "name"), exportStatement);
+		} else if (elementName.equals("import")) {
+			if (manifestInfo.requires == null) {
+				manifestInfo.requires = new ArrayList();
+				// to avoid cycles
+				if (!manifestInfo.pluginId.equals("org.eclipse.core.runtime"))
+					manifestInfo.requires.add("org.eclipse.core.runtime");
+			}
+			String plugin = attributes.getValue("", "plugin");
+			if (plugin == null)
+				return;
+
+			if (plugin.equals("org.eclipse.core.boot") || plugin.equals("org.eclipse.core.runtime"))
+				return;
+
+			String version = attributes.getValue("", "version");
+			String export = attributes.getValue("", "export");
+			String optional = attributes.getValue("", "optional");
+			String match = attributes.getValue("", "match");
+			String modImport = plugin;
+			if (version != null) {
+				modImport += "; " + Constants.BUNDLE_VERSION_ATTRIBUTE + "=" + version;
+			}
+			if (export != null) {
+				modImport += "; " + Constants.PROVIDE_PACKAGES_ATTRIBUTE + "=" + export;
+			}
+			if (optional != null) {
+				modImport += ";" + Constants.OPTIONAL_ATTRIBUTE + "=" + "true";
+			}
+			if (match != null) {
+				modImport += ";" + Constants.VERSION_MATCH_ATTRIBUTE + "=";
+				if (match.equalsIgnoreCase("perfect")) {
+					modImport += Constants.VERSION_MATCH_PERFECT;
+				} else if (match.equalsIgnoreCase("equivalent")) {
+					modImport += Constants.VERSION_MATCH_EQUIVALENT;
+				} else if (match.equalsIgnoreCase("compatible")) {
+					modImport += Constants.VERSION_MATCH_COMPATIBLE;
+				} else if (match.equalsIgnoreCase("greaterOrEqual")) {
+					modImport += Constants.VERSION_MATCH_GREATERTHANOREQUAL;
+				}
+			}
+			manifestInfo.requires.add(modImport);
+		} else if (elementName.equals("packages")) {
+			//packages filtering is done globally
+			if (manifestInfo.filters == null)
+				manifestInfo.filters = new HashSet(4);
+			String prefixString = attributes.getValue("", "prefixes");
+			StringTokenizer tok = new StringTokenizer(prefixString, ",");
+			while (tok.hasMoreTokens()) {
+				manifestInfo.filters.add(tok.nextToken().trim());
+			}
+		} else if (elementName.equals("export")) {
+			//Add the export to the last library encountered
+			String exportFilter = (String) attributes.getValue("", "name");
+			StringTokenizer tok = new StringTokenizer(exportFilter, ",");
+			while (tok.hasMoreTokens()) {
+				exportStatement.add(tok.nextToken().trim());
+			}
+		}
+	}
+
+	private SAXParserFactory acquireXMLParsing() {
+		parserReference = ConfigurationActivator.getBundleContext().getServiceReference("javax.xml.parsers.SAXParserFactory");
+		if (parserReference == null)
+			return null;
+		return (SAXParserFactory) ConfigurationActivator.getBundleContext().getService(parserReference);
+	}
+
+	private void releaseXMLParsing() {
+		if (parserReference != null)
+			ConfigurationActivator.getBundleContext().ungetService(parserReference);
+	}
+
+	public static void main(String[] args) throws Exception {
+		for (int i = 0; i < args.length; i++)
+			System.out.println(new PluginParser().parse(args[i]));
+	}
+
+	public class PluginInfo implements IPluginInfo {
+		private String schemaVersion;
+		private String pluginId;
+		private String version;
+		// TODO libraries and requires should be ordered.
+		private Map libraries; //represent the libraries and their export statement
+		private ArrayList requires;
+		private String pluginClass;
+		private String masterPluginId;
+		private String masterVersion;
+		private Set filters;
+
+		public boolean isFragment() {
+			return masterPluginId != null;
+		}
+		public String toString() {
+			return "plugin-id: " + pluginId + "  version: " + version + " libraries: " + libraries + " class:" + pluginClass + " master: " + masterPluginId + " master-version: " + masterVersion + " requires: " + requires;
+		}
+		public Map getLibraries() {
+			if (libraries == null)
+				return new HashMap(0);
+			return libraries;
+		}
+
+		public String[] getRequires() {
+			if (requires == null)
+				return new String[] { "org.eclipse.core.runtime" };
+
+			if (schemaVersion == null) {
+				//Add elements on the requirement list of ui and help. 
+				for (int i = 0; i < requires.size(); i++) {
+					if ("org.eclipse.ui".equals(requires.get(i))) { //$NON-NLS-1$
+						requires.add(i + 1, "org.eclipse.ui.workbench.texteditor;" + Constants.OPTIONAL_ATTRIBUTE + "=" + "true");
+						requires.add(i + 1, "org.eclipse.ui.jface.text;" + Constants.OPTIONAL_ATTRIBUTE + "=" + "true");
+						requires.add(i + 1, "org.eclipse.ui.editors;" + Constants.OPTIONAL_ATTRIBUTE + "=" + "true");
+						requires.add(i + 1, "org.eclipse.ui.views;" + Constants.OPTIONAL_ATTRIBUTE + "=" + "true");
+						requires.add(i + 1, "org.eclipse.ui.ide;" + Constants.OPTIONAL_ATTRIBUTE + "=" + "true");
+					} else if ("org.eclipse.help".equals(requires.get(i))) { //$NON-NLS-1$
+						requires.add(i + 1, "org.eclipse.help.base;" + Constants.OPTIONAL_ATTRIBUTE + "=" + "true");
+					}
+				}
+			}
+
+			String[] requireBundles = new String[requires.size()];
+			requires.toArray(requireBundles);
+			return requireBundles;
+		}
+
+		public String getMasterId() {
+			return masterPluginId;
+		}
+		public String getMasterVersion() {
+			return masterVersion;
+		}
+		public String getPluginClass() {
+			return pluginClass;
+		}
+		public String getUniqueId() {
+			return pluginId;
+		}
+		public String getVersion() {
+			return version;
+		}
+		public Set getPackageFilters() {
+			return filters;
+		}
+		public String[] getLibrariesName() {
+			if (libraries == null)
+				return new String[0];
+			Set names = libraries.keySet();
+			return (String[]) names.toArray(new String[names.size()]);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.xml.sax.ContentHandler#processingInstruction
+	 * @since 3.0
+	 */
+	public void processingInstruction(String target, String data) throws SAXException {
+		// Since 3.0, a processing instruction of the form <?eclipse version="3.0"?> at
+		// the start of the manifest file is used to indicate the plug-in manifest
+		// schema version in effect. Pre-3.0 (i.e., 2.1) plug-in manifest files do not
+		// have one of these, and this is how we can distinguish the manifest of a
+		// pre-3.0 plug-in from a post-3.0 one (for compatibility tranformations).
+		if (target.equalsIgnoreCase("eclipse")) { //$NON-NLS-1$
+			// just the presence of this processing instruction indicates that this
+			// plug-in is at least 3.0
+			schemaVersion = "3.0"; //$NON-NLS-1$
+			StringTokenizer tokenizer = new StringTokenizer(data, "=\""); //$NON-NLS-1$
+			while (tokenizer.hasMoreTokens()) {
+				String token = tokenizer.nextToken();
+				if (token.equalsIgnoreCase("version")) { //$NON-NLS-1$
+					if (!tokenizer.hasMoreTokens()) {
+						break;
+					}
+					schemaVersion = tokenizer.nextToken();
+					break;
+				}
+			}
+		}
+	}
+}
