*** empty log message ***
diff --git a/bundles/org.eclipse.core.boot/boot.xml b/bundles/org.eclipse.core.boot/boot.xml
new file mode 100644
index 0000000..4cd2900
--- /dev/null
+++ b/bundles/org.eclipse.core.boot/boot.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<requires>
+   <import plugin="org.eclipse.core.runtime" version="2.0.0" match="equivalent"/>
+</requires>
diff --git a/bundles/org.eclipse.core.boot/build.properties b/bundles/org.eclipse.core.boot/build.properties
index f7a041b..3bb6a44 100644
--- a/bundles/org.eclipse.core.boot/build.properties
+++ b/bundles/org.eclipse.core.boot/build.properties
@@ -1,4 +1,4 @@
 source.boot.jar=src/
-bin.includes=plugin.xml,*.jar,plugin.properties,about.html
+bin.includes=plugin.xml,boot.xml,*.jar,plugin.properties,about.html
 javadoc.packages=org.eclipse.core.boot.*
 
diff --git a/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/InternalBootLoader.java b/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/InternalBootLoader.java
index 66d63e3..271c7b9 100644
--- a/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/InternalBootLoader.java
+++ b/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/InternalBootLoader.java
@@ -205,7 +205,7 @@
 	// Get the location of this class and compute the install location.
 	// this involves striping off last element (jar or directory) 
 	URL url = InternalBootLoader.class.getProtectionDomain().getCodeSource().getLocation();
-	String path = url.getFile();
+	String path = decode(url.getFile());
 	if (path.endsWith("/"))
 		path = path.substring(0, path.length() - 1);
 	int ix = path.lastIndexOf('/');
@@ -228,6 +228,57 @@
 	}
 	return installURL;
 }
+/**
+ * Returns a string representation of the given URL String.  This converts
+ * escaped sequences (%..) in the URL into the appropriate characters.
+ * NOTE: due to class visibility there is a copy of this method
+ *       in Main (the launcher)
+ */
+public static String decode(String urlString) {
+	//try to use Java 1.4 method if available
+	try {
+		Class clazz = URLDecoder.class;
+		Method method = clazz.getDeclaredMethod("decode", new Class[] {String.class, String.class});//$NON-NLS-1$
+		//first encode '+' characters, because URLDecoder incorrectly converts 
+		//them to spaces on certain class library implementations.
+		if (urlString.indexOf('+') >= 0) {
+			int len = urlString.length();
+			StringBuffer buf = new StringBuffer(len);
+			for (int i = 0; i < len; i++) {
+				char c = urlString.charAt(i);
+				if (c == '+')
+					buf.append("%2B");//$NON-NLS-1$
+				else
+					buf.append(c);
+			}
+			urlString = buf.toString();
+		}
+		Object result = method.invoke(null, new Object[] {urlString, "UTF-8"});//$NON-NLS-1$
+		if (result != null)
+			return (String)result;
+	} catch (Exception e) {
+	}
+	//decode URL by hand
+	int len = urlString.length();
+	ByteArrayOutputStream os = new ByteArrayOutputStream(len);
+	for (int i = 0; i < len;) {
+		char c = urlString.charAt(i++);
+		if (c == '%') {
+			if (len >= i + 2) {
+				os.write(Integer.parseInt(urlString.substring(i, i + 2), 16));
+			}
+			i += 2;
+		} else {
+			os.write(c);
+		}
+	}
+	try {
+		return new String(os.toByteArray(), "UTF-8");//$NON-NLS-1$
+	} catch (UnsupportedEncodingException e) {
+		//use default encoding
+		return new String(os.toByteArray());
+	}
+}
 private static String[] getListOption(String option) {
 	String filter = options.getProperty(option);
 	if (filter == null)
@@ -266,7 +317,8 @@
 private static Object[] getPlatformClassLoaderPath() {
 
 	PlatformConfiguration config = getCurrentPlatformConfiguration();
-	String execBase = config.getPluginPath(RUNTIMENAME).toExternalForm();
+	PlatformConfiguration.BootDescriptor bd = config.getPluginBootDescriptor(RUNTIMENAME);
+	String execBase = bd.getPluginDirectoryURL().toExternalForm();
 	if (execBase == null)
 		execBase = getInstallURL() + RUNTIMEDIR;
 
@@ -284,8 +336,11 @@
 		}
 	}
 	ArrayList list = new ArrayList(5);
-	list.add("runtime.jar");
-	list.add(exportAll);
+	String[] libs = bd.getLibraries();
+	for (int i=0; i<libs.length; i++) {
+		list.add(libs[i]);
+		list.add(exportAll);
+	}
 
 	// add in the class path entries spec'd in the config.
 	for (Iterator i = list.iterator(); i.hasNext();) {
diff --git a/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/PlatformConfiguration.java b/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/PlatformConfiguration.java
index 067243d..0471c94 100644
--- a/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/PlatformConfiguration.java
+++ b/bundles/org.eclipse.core.boot/src/org/eclipse/core/internal/boot/PlatformConfiguration.java
@@ -36,6 +36,8 @@
 	private boolean transientConfig = false;
 	private File cfgLockFile;
 	private RandomAccessFile cfgLockFileRAF;
+	private BootDescriptor runtimeDescriptor; 
+	private BootDescriptor xmlDescriptor; 
 	
 	private static String cmdConfiguration = null;
 	private static String cmdFeature = null;
@@ -46,6 +48,11 @@
 	private static boolean cmdDev = false;
 
 	static boolean DEBUG = false;
+	
+	private static final String BOOT_XML = "boot.xml";
+	private static final String BOOT_PLUGIN_ID = "org.eclipse.core.boot";
+	private static final String RUNTIME_PLUGIN_ID = "org.eclipse.core.runtime";
+	private static final String XML_PLUGIN_ID = "org.apache.xerces";
 
 	private static final String PLUGINS = "plugins";
 	private static final String FEATURES = "features";
@@ -517,6 +524,12 @@
 		private static final String VER_SEPARATOR = ".";
 		private static final String ID_SEPARATOR = "_";
 		
+		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("")) 
 				return;
@@ -530,11 +543,11 @@
 			 this.identifier = s;		
 		}
 		
-		public boolean identifierEquals(String id) {
+		public boolean equalIdentifiers(VersionedIdentifier id) {
 			if (id == null)
 				return identifier == null;
 			else
-				return id.equals(identifier);
+				return id.identifier.equals(identifier);
 		}		
 		
 		public int compareVersion(VersionedIdentifier id) {
@@ -544,23 +557,23 @@
 				else return 1;
 			}
 
-			if (major > id.major) return 1;
-			if (major < id.major) return -1;
-			if (minor > id.minor) return 1;
-			if (minor < id.minor) return -1;	
-			if (service > id.service) return 1;
-			if (service < id.service) 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 -1;
+				return LESS_THAN;
 			else if (result>0)
-				return 1;
+				return EQUIVALENT;
 			else
-				return 0;
+				return EQUAL;
 		}	
 		
 		private void parseVersion(String v) {				
@@ -626,17 +639,30 @@
 	 * during the platform startup sequence before full xml plugin is available.
 	 */
 	public static class Parser {
-	
-		ArrayList elements = new ArrayList();
+		
+		private ArrayList elements = new ArrayList();
 	
 		/*
 		 * Construct parser for the specified file
 		 */
 		public Parser(File file) {
-			load(file);	
+			try {
+				load(new FileInputStream(file));
+			} catch (Exception e) {
+			}	
 		}
 	
 		/*
+		 * Construct parser for the specified URL
+		 */
+		public Parser(URL url) {
+			try {
+				load(url.openStream());
+			} catch (Exception e) {
+			}
+		}		
+	
+		/*
 		 * 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>".
@@ -694,16 +720,16 @@
 			return null;
 		}
 	
-		private void load(File file) {	
-			if (!file.exists())
-				return;		
+		private void load(InputStream is) {
+			if (is == null)
+				return;
 			
 			// read file	
 			StringBuffer xml = new StringBuffer(4096);
 			char[] iobuf = new char[4096];
-			FileReader r = null;
+			InputStreamReader r = null;
 			try {
-				r = new FileReader(file);
+				r = new InputStreamReader(is);
 				int len = r.read(iobuf, 0, iobuf.length);
 				while (len != -1) {
 					xml.append(iobuf, 0, len);
@@ -728,6 +754,36 @@
 			}
 		}
 	}
+	
+	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) throws IOException {
 		this.sites = new HashMap();
@@ -1125,76 +1181,21 @@
 		}
 	}
 	
-	URL getPluginPath(String pluginId) {
-		return getPluginPath(pluginId, null);
-	}	
-		
-	// This method is currently public because it is called by InternalPlatform.
-	// However, it is NOT intended as API
-	public URL getPluginPath(String pluginId, String versionId) {
-		// return the plugin path element for the specified plugin. This method
-		// is used during boot processing to obtain "kernel" plugins whose
-		// class loaders must be created prior to the plugin registry being 
-		// available (ie. loaders needed to create the plugin registry)
-		// must be created 
-				
-		ISiteEntry[] sites = getConfiguredSites();
-		if (sites == null || sites.length == 0)
-			return null;
-				
-		// for now look for the "latest" version of the requested plugin
-		// using naming convention of the installer and the policy set for
-		// the site
-		// FIXME: the current code in this method implements the R1.0 "best guess"
-		//        algorithm
-		VersionedIdentifier savedVid = new VersionedIdentifier(null);
-		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("/");
-				if (ix != -1)
-					pluginDir = pluginDir.substring(0,ix);
-				if (pluginDir.equals(""))
-					continue; // bad entry ... skip
-												
-				VersionedIdentifier vid = new VersionedIdentifier(pluginDir);
-				if (vid.identifierEquals(pluginId)) {
-					if (vid.compareVersion(savedVid) >= 0) {
-						savedVid = vid;
-						savedEntry = plugins[i];
-						savedURL = ((SiteEntry)sites[j]).getResolvedURL();
-					}
-				}			
-			}				
-		}			
+	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 (savedEntry == null)
+		if (RUNTIME_PLUGIN_ID.equals(id))
+			return runtimeDescriptor;
+		else if (XML_PLUGIN_ID.equals(id))
+			return xmlDescriptor;
+		else
 			return null;
-				
-		// callers are expecting a directory URL
-		if (!savedEntry.endsWith("/")) {
-			int ix = savedEntry.lastIndexOf("/");
-			if (ix == -1)
-				return null; // bad entry
-			savedEntry = savedEntry.substring(0,ix+1); // include trailing separator
-		}
-			
-		try {
-			return new URL(savedURL,savedEntry);
-		} catch(MalformedURLException e) {
-			return null;
-		}
 	}
 	
+		
 	static PlatformConfiguration getCurrent() {
 		return currentPlatformConfiguration;
 	}
@@ -1785,30 +1786,269 @@
 	}
 	
 	private void locateDefaultPlugins() {
-		// parse core.boot plugin.xml
-		// -> get its import for core.runtime
 		
-		// search plugin path for best match for core.runtime
-		// -> parse all found to get correct info
+		// determine the runtime for the currently executing boot loader
+		HashMap runtimeImport = getRuntimeImport();
 		
-		// parse core.runtime plugin.xml
-		//-> get its import for xerces
+		// locate runtime plugin matching the import from boot
+		URL runtimePluginPath = getPluginPath(runtimeImport);
+		if (runtimePluginPath == null) 
+			throw new RuntimeException("Fatal Error: Unable to locate matching org.eclipse.core.runtime plugin");
 		
-		// search plugin path for best match for xerces
-		// -> parse all found to get correct info
+		// get boot descriptor for runtime plugin
+		runtimeDescriptor = createPluginBootDescriptor(runtimePluginPath);
 		
-		// parse xerces plugin.xml
-		// -> get its <library> entries ... all of them	
+		// determine the xml plugin for the selected runtime
+		HashMap xmlImport = getImport(runtimePluginPath, XML_PLUGIN_ID);
+		
+		// locate xml plugin matching the import from runtime plugin
+		URL xmlPluginPath = getPluginPath(xmlImport);
+		if (xmlPluginPath == null) 
+			throw new RuntimeException("Fatal Error: Unable to locate matching org.apache.xerces plugin");
+				
+		// get boot descriptor for xml plugin
+		xmlDescriptor = createPluginBootDescriptor(xmlPluginPath);
 	}
 	
-	private File locateBootPluginXML(String path) {
-		// starting path is the boot load location (jar or directory)
-		// -> trip off .jar
+	private HashMap getRuntimeImport() {		
+		// determine the load directory location of the boot loader
+		URL url = InternalBootLoader.class.getProtectionDomain().getCodeSource().getLocation();
+		String path = InternalBootLoader.decode(url.getFile());
+		File base = new File(path);
+		if (!base.isDirectory())
+			base = base.getParentFile(); // was loaded from jar
+			
+		// find the plugin.xml (need to search because in dev mode
+		// we can have some extra directory entries)
+		File xml = null;
+		while(base != null) {
+			xml = new File(base, BOOT_XML);
+			if (xml.exists())
+				break;
+			base = base.getParentFile();
+		}		
+		if (xml == null)		
+			throw new RuntimeException("Fatal Error: Unable to locate boot.xml file for executing org.eclipse.core.boot");
+			
+		try {
+			return getImport(xml.toURL(), RUNTIME_PLUGIN_ID);
+		} catch(MalformedURLException e) {
+			return null;
+		}
+	}
+				
+				
+	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"))
+					return true;
+				else
+					return false;
+			}
+			public boolean select(String element, HashMap attributes) {
+				if (attributes == null)
+					return false;
+				String plugin = (String) attributes.get("plugin");
+				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"))
+					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"))
+					return true;
+				else
+					return false;
+			}
+			public boolean select(String element, HashMap attributes) {
+				if (attributes == null)
+					return false;
+				String lib = (String) attributes.get("name");
+				if (lib != null)
+					libs.add(lib);
+				return false; // accumulate all library elements
+			}
+		};
 		
-		// recursively try to get <dir>/plugin.xml, until we have no parent
-		// -> terminal error if not found
+		// 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");
+			version = (String)attributes.get("version");
+		}
+		if (id == null)
+			id = "";
+		if (version == null)
+			version = "0.0.0";		
+		
+		p.getElement(librarySel);
+		String[] libraries = (String[])libs.toArray(new String[0]);
+				
+		String dir = entry.getFile();
+		int ix = dir.lastIndexOf("/");
+		dir = dir.substring(0,ix+1);
+		URL dirURL = null;
+		try {
+			dirURL = new URL(entry.getProtocol(), entry.getHost(), entry.getPort(), dir);
+		} catch(MalformedURLException e) {
+		}
+		
+		// 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");
+		String version = (String) importElement.get("version");
+		String match = (String) importElement.get("match");
+		if (pid == null)
+			return null; // bad <import> element
+		if (version == null)
+			id = new VersionedIdentifier(pid);
+		else {
+			id = new VersionedIdentifier(pid+"_"+version);
+			if (match == null)
+				match = "compatible";
+		}
+		
+		// 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("/");
+				if (ix != -1)
+					pluginDir = pluginDir.substring(0,ix);
+				if (pluginDir.equals(""))
+					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) {
+						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"))
+								return true;
+							else
+								return false;
+							}
+							public boolean select(String element, HashMap attributes) {
+								if (attributes == null)
+									return false;
+								String plugin = (String) attributes.get("id");
+								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)
+							continue; // bad xml ... skip
+						pluginDir += "_" + pluginVersion;
+						vid = new VersionedIdentifier(pluginDir);
+					}					
+					
+					// do the comparison
+					int result;
+					if ((result = vid.compareVersion(savedVid)) >= 0) {
+						if ("greaterOrEqual".equals(match)) {
+							 if (result > VersionedIdentifier.GREATER_THAN) 
+								continue;
+						} else if ("compatible".equals(match)) {
+							 if (result > VersionedIdentifier.COMPATIBLE) 
+								continue;
+						} else if ("equivalent".equals(match)) {
+							 if (result > VersionedIdentifier.EQUIVALENT) 
+								continue;
+						} else if ("perfect".equals(match)) {
+							 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();
+					}
+				}			
+			}				
+		}			
 
-		return null;
+		if (savedEntry == null)
+			return null;
+							
+		try {
+			return new URL(savedURL,savedEntry);
+		} catch(MalformedURLException e) {
+			return null;
+		}
 	}
 	
 	private void write(PrintWriter w) {
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java
index 143955a..6ecc099 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java
@@ -68,8 +68,6 @@
 	// default plugin data
 	private static final String PI_XML = "org.apache.xerces";
 	private static final String PLUGINSDIR = "plugins/";
-	private static final String XML_VERSION = "1.2.1";
-	private static final String XML_JAR = "xerces.jar";
 	private static final String XML_LOCATION = "plugins/" + PI_XML + "/";
 	
 	// execution options
@@ -209,14 +207,14 @@
 	// create a plugin descriptor which is sufficient to be able to create
 	// the class loader through the normal channels.
 	Factory factory = new InternalFactory(null);
-	PluginDescriptor descriptor = (PluginDescriptor) factory.createPluginDescriptor();
+	PluginDescriptor descriptor = (PluginDescriptor) factory.createPluginDescriptor();	
 	descriptor.setEnabled(true);
 	descriptor.setId(PI_XML);
-	descriptor.setVersion(XML_VERSION);
-
+	PlatformConfiguration config = InternalBootLoader.getCurrentPlatformConfiguration();
+	PlatformConfiguration.BootDescriptor bd = config.getPluginBootDescriptor(PI_XML);
+	descriptor.setVersion(bd.getVersion());
 	try {
-		PlatformConfiguration config = InternalBootLoader.getCurrentPlatformConfiguration();
-		URL url = config.getPluginPath(PI_XML, XML_VERSION);
+		URL url = bd.getPluginDirectoryURL();
 		if (url == null)
 			url = new URL(BootLoader.getInstallURL(), XML_LOCATION);
 		descriptor.setLocation(url.toExternalForm());
@@ -224,10 +222,15 @@
 		// ISSUE: What to do when this fails.  It's pretty serious
 	}
 
-	LibraryModel lib = factory.createLibrary();
-	lib.setName(XML_JAR);
-	lib.setExports(new String[] { "*" });
-	descriptor.setRuntime(new LibraryModel[] { lib });
+	ArrayList libList = new ArrayList();
+	String[] libs = bd.getLibraries();
+	for (int i=0; i<libs.length; i++) {
+		LibraryModel lib = factory.createLibrary();
+		lib.setName(libs[i]);
+		lib.setExports(new String[] { "*" });
+		libList.add(lib);
+	}
+	descriptor.setRuntime((LibraryModel[]) libList.toArray(new LibraryModel[0]));
 
 	// use the fake plugin descriptor to create the desired class loader.
 	// Since this class loader will be used before the plugin registry is installed,