diff --git a/plugins/org.eclipse.jst.server.core/src/org/eclipse/jst/server/core/RuntimeClasspathProviderDelegate.java b/plugins/org.eclipse.jst.server.core/src/org/eclipse/jst/server/core/RuntimeClasspathProviderDelegate.java
index bdae750..91bc0d0 100644
--- a/plugins/org.eclipse.jst.server.core/src/org/eclipse/jst/server/core/RuntimeClasspathProviderDelegate.java
+++ b/plugins/org.eclipse.jst.server.core/src/org/eclipse/jst/server/core/RuntimeClasspathProviderDelegate.java
@@ -1,390 +1,406 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.jst.server.core;
-
-import java.io.File;
-import java.util.*;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jdt.core.IClasspathAttribute;
-import org.eclipse.jdt.core.IClasspathContainer;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jst.server.core.internal.IMemento;
-import org.eclipse.jst.server.core.internal.JavaServerPlugin;
-import org.eclipse.jst.server.core.internal.RuntimeClasspathContainer;
-import org.eclipse.jst.server.core.internal.Trace;
-import org.eclipse.jst.server.core.internal.XMLMemento;
-import org.eclipse.wst.server.core.IRuntime;
-/**
- * A runtime classpath provider provides the classpath for a Java server runtime.
- * This provider is scoped by runtime type and may provide the classpath for multiple
- * runtime instances.
- * <p>
- * This abstract class is intended to be extended only by clients
- * to extend the <code>runtimeClasspathProviders</code> extension point.
- * </p>
- * <p>
- * <b>Provisional API:</b> This class/interface is part of an interim API that is still under development and expected to 
- * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
- * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
- * (repeatedly) as the API evolves.
- * </p>
- * 
- * @plannedfor 3.0
- */
-public abstract class RuntimeClasspathProviderDelegate {
-	protected class SourceAttachmentUpdate {
-		String runtimeId;
-		IPath entry;
-		IPath sourceAttachmentPath;
-		IPath sourceAttachmentRootPath;
-		IClasspathAttribute[] attributes;
-	}
-
-	private volatile List<SourceAttachmentUpdate> sourceAttachments;
-
-	private String extensionId;
-
-	private Map<String, IPath> runtimePathMap = Collections.synchronizedMap(new HashMap<String, IPath>());
-
-	private Map<String, Integer> previousClasspath = Collections.synchronizedMap(new HashMap<String, Integer>());
-
-	public RuntimeClasspathProviderDelegate() {
-		// default constructor
-	}
-
-	/**
-	 * Initializes this classpath provider with its life-long id.
-	 * <p>
-	 * This method is called by the framework.
-	 * Clients should never call this method.
-	 * </p>
-	 * @param id the extension id
-	 */
-	public final void initialize(String id) {
-		extensionId = id;
-	}
-
-	/**
-	 * Resolves (creates the classpath entries for) the classpath container with
-	 * the given runtime and the given classpath container id (returned from
-	 * getClasspathEntryIds()). If the classpath container cannot be resolved
-	 * (for instance, if the runtime does not exist), return null.
-	 * 
-	 * @param runtime the runtime to resolve the container for
-	 * @return an array of classpath entries for the container, or null if the
-	 *   container could not be resolved
-	 * @deprecated use resolveClasspathContainer(IProject, IRuntime) instead
-	 */
-	public IClasspathEntry[] resolveClasspathContainer(IRuntime runtime) {
-		return null;
-	}
-
-	/**
-	 * Resolves (creates the classpath entries for) the classpath container with
-	 * the given runtime and the given classpath container id (returned from
-	 * getClasspathEntryIds()). If the classpath container cannot be resolved
-	 * (for instance, if the runtime does not exist), return null.
-	 * 
-	 * @param project the project to resolve
-	 * @param runtime the runtime to resolve the container for
-	 * @return an array of classpath entries for the container, or null if the
-	 *   container could not be resolved
-	 */
-	public IClasspathEntry[] resolveClasspathContainer(IProject project, IRuntime runtime) {
-		return null;
-	}
-
-	/**
-	 * Resolve the classpath container.
-	 * 
-	 * @param runtime a runtime
-	 * @return a possibly empty array of classpath entries
-	 * @deprecated should use resolveClasspathContainerImpl(IProject, IRuntime) instead
-	 */
-	public IClasspathEntry[] resolveClasspathContainerImpl(IRuntime runtime) {
-		return resolveClasspathContainerImpl(null, runtime);
-	}
-
-	/**
-	 * Resolve the classpath container.
-	 * 
-	 * @param project a project
-	 * @param runtime a runtime
-	 * @return a possibly empty array of classpath entries
-	 */
-	public IClasspathEntry[] resolveClasspathContainerImpl(IProject project, IRuntime runtime) {
-		if (runtime == null)
-			return new IClasspathEntry[0];
-		runtimePathMap.put(runtime.getId(), runtime.getLocation());
-		IClasspathEntry[] entries = resolveClasspathContainer(project, runtime);
-		if (entries == null)
-			entries = resolveClasspathContainer(runtime);
-		
-		if (entries == null)
-			entries = new IClasspathEntry[0];
-		
-		synchronized (this) {
-			if (sourceAttachments == null)
-				load();
-		}
-		List<SourceAttachmentUpdate> srcAttachments = sourceAttachments;
-
-		if (srcAttachments != null) {
-			int size = entries.length;
-			int size2 = srcAttachments.size();
-			for (int i = 0; i < size; i++) {
-				for (int j = 0; j < size2; j++) {
-					SourceAttachmentUpdate sau = srcAttachments.get(j);
-					if (sau.runtimeId.equals(runtime.getId()) && sau.entry.equals(entries[i].getPath())) {
-						IClasspathAttribute[] consolidatedClasspathAttributes = consolidateClasspathAttributes(sau.attributes, entries[i].getExtraAttributes());
-						entries[i] = JavaCore.newLibraryEntry(entries[i].getPath(), sau.sourceAttachmentPath, sau.sourceAttachmentRootPath, entries[i].getAccessRules(), consolidatedClasspathAttributes, false);
-						break;
-					}
-				}
-			}
-		}
-		
-		String key = project.getName() + "/" + runtime.getId();
-		if (!previousClasspath.containsKey(key))
-			previousClasspath.put(key, new Integer(entries.length));
-		else {
-			Integer previousEntries = previousClasspath.get(key);
-			
-			if ((previousEntries == null) || (previousEntries.intValue() != entries.length)) {
-				if (Trace.FINEST) {
-					Trace.trace(Trace.STRING_FINEST, "Classpath update: " + key + " " + entries);
-				}
-				previousClasspath.put(key, new Integer(entries.length));
-				
-				IPath path = new Path(RuntimeClasspathContainer.SERVER_CONTAINER);
-				path = path.append(extensionId).append(runtime.getId());
-				try {
-					IJavaProject javaProject = JavaCore.create(project);
-					JavaCore.setClasspathContainer(path, new IJavaProject[] { javaProject },
-							new IClasspathContainer[] { null }, new NullProgressMonitor());
-				} catch (Exception e) {
-					if (Trace.WARNING) {
-						Trace.trace(Trace.STRING_WARNING, "Error updating classpath", e);
-					}
-				}
-			}
-		}
-		
-		return entries;
-	}
-
-	/*
-	 * Returns true if there are any changes in the runtime since the last time that the
-	 * classpath was resolved which may affect the classpath, and false otherwise. This
-	 * method is used to check projects when a runtime changes and automatically rebuild
-	 * them if necessary.
-	 * 
-	 * @param runtime a runtime
-	 * @return <code>true</code> if the classpath may change due to a change in the runtime,
-	 *    and <code>false</code> if there are no changes
-	 */
-	public boolean hasRuntimeClasspathChanged(IRuntime runtime) {
-		try {
-			IPath path = runtimePathMap.get(runtime.getId());
-			return (path != null && !path.equals(runtime.getLocation()));
-		} catch (Exception e) {
-			// ignore
-		}
-		return false;
-	}
-
-	private static void addJarFiles(File dir, List<IClasspathEntry> list, boolean includeSubdirectories) {
-		int depth = 0;
-		if (includeSubdirectories)
-			depth = 2;
-		addJarFiles(dir, list, depth);
-	}
-
-	private static void addJarFiles(File dir, List<IClasspathEntry> list, int depth) {
-		if (dir == null)
-			throw new IllegalArgumentException();
-		
-		File[] files = dir.listFiles();
-		if (files != null) {
-			for (File file : files) {
-				if (file.isDirectory() && depth > 0) {
-					addJarFiles(file, list, depth - 1);
-				} else if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".zip")) {
-					IPath path = new Path(file.getAbsolutePath());
-					list.add(JavaCore.newLibraryEntry(path, null, null));
-				}
-			}
-		}
-	}
-
-	/**
-	 * Add library entries to the given list for every jar file found in the
-	 * given directory. Optionally search subdirectories as well.
-	 * 
-	 * @param list a list
-	 * @param dir a directory
-	 * @param includeSubdirectories <code>true</code> to include subdirectories, and
-	 *    <code>false</code> otherwise
-	 */
-	protected static void addLibraryEntries(List<IClasspathEntry> list, File dir, boolean includeSubdirectories) {
-		if (dir == null)
-			throw new IllegalArgumentException();
-		addJarFiles(dir, list, includeSubdirectories);
-	}
-
-	/**
-	 * Request that the classpath container for the given runtime and id be updated
-	 * with the given classpath container entries.
-	 * 
-	 * @param runtime a runtime
-	 * @param entries an array of classpath entries
-	 */
-	public void requestClasspathContainerUpdate(IRuntime runtime, IClasspathEntry[] entries) {
-		// default behaviour is to save the source path entries
-		if (runtime == null || entries == null)
-			return;
-		
-		// find the source attachments
-		List<SourceAttachmentUpdate> srcAttachments = new ArrayList<SourceAttachmentUpdate>();
-		
-		for (IClasspathEntry entry : entries) {
-			if (entry.getSourceAttachmentPath() != null || (entry.getExtraAttributes() != null && entry.getExtraAttributes().length > 0)) {
-				SourceAttachmentUpdate sau = new SourceAttachmentUpdate();
-				sau.runtimeId = runtime.getId();
-				sau.entry = entry.getPath();
-				sau.sourceAttachmentPath = entry.getSourceAttachmentPath();
-				sau.sourceAttachmentRootPath = entry.getSourceAttachmentRootPath();
-				sau.attributes = entry.getExtraAttributes();
-				srcAttachments.add(sau);
-			}
-		}
-		sourceAttachments = srcAttachments;
-		save();
-	}
-
-	/**
-	 * Load source attachment info.
-	 */
-	private void load() {
-		List<SourceAttachmentUpdate> srcAttachments = new ArrayList<SourceAttachmentUpdate>();
-		
-		String id = extensionId;
-		String filename = JavaServerPlugin.getInstance().getStateLocation().append(id + ".xml").toOSString();
-		if (!(new File(filename)).exists())
-			return;
-		
-		try {
-			IMemento memento = XMLMemento.loadMemento(filename);
-			
-			IMemento[] children = memento.getChildren("source-attachment");
-			for (IMemento child : children) {
-				try {
-					SourceAttachmentUpdate sau = new SourceAttachmentUpdate();
-					sau.runtimeId = child.getString("runtime-id");
-					String temp = child.getString("entry");
-					if (temp != null)
-						sau.entry = new Path(temp);
-					temp = child.getString("source-attachment-path");
-					if (temp != null)
-						sau.sourceAttachmentPath = new Path(temp);
-					temp = child.getString("source-attachment-root-path");
-					if (temp != null)
-						sau.sourceAttachmentRootPath = new Path(temp);
-					IMemento[] attrChildren = child.getChildren("attribute");
-					if (attrChildren != null) {
-						int size2 = attrChildren.length;
-						sau.attributes = new IClasspathAttribute[size2];
-						for (int j = 0; j < size2; j++) {
-							String name = attrChildren[j].getString("name");
-							String value = attrChildren[j].getString("value");
-							sau.attributes[j] = JavaCore.newClasspathAttribute(name, value);
-						}
-					}
-					srcAttachments.add(sau);
-				} catch (Exception e) {
-					if (Trace.WARNING) {
-						Trace.trace(Trace.STRING_WARNING, "Could not load source attachment: " + e);
-					}
-				}
-			}
-		} catch (Exception e) {
-			if (Trace.WARNING) {
-				Trace.trace(Trace.STRING_WARNING, "Could not load source path info", e);
-			}
-		}
-		sourceAttachments = srcAttachments;
-	}
-
-	/**
-	 * Save source attachment info.
-	 */
-	private synchronized void save() {
-		List<SourceAttachmentUpdate> srcAttachments = sourceAttachments;
-		if (srcAttachments == null)
-			return;
-		String id = extensionId;
-		String filename = JavaServerPlugin.getInstance().getStateLocation().append(id + ".xml").toOSString();
-		try {
-			XMLMemento memento = XMLMemento.createWriteRoot("classpath");
-
-			Iterator iterator = srcAttachments.iterator();
-			while (iterator.hasNext()) {
-				SourceAttachmentUpdate sau = (SourceAttachmentUpdate) iterator.next();
-				IMemento child = memento.createChild("source-attachment");
-				child.putString("runtime-id", sau.runtimeId);
-				if (sau.entry != null)
-					child.putString("entry", sau.entry.toPortableString());
-				if (sau.sourceAttachmentPath != null)
-					child.putString("source-attachment-path", sau.sourceAttachmentPath.toPortableString());
-				if (sau.sourceAttachmentRootPath != null)
-					child.putString("source-attachment-root-path", sau.sourceAttachmentRootPath.toPortableString());
-				if (sau.attributes != null) {
-					for (IClasspathAttribute attr : sau.attributes) {
-						IMemento attrChild = child.createChild("attribute");
-						attrChild.putString("name", attr.getName());
-						attrChild.putString("value", attr.getValue());
-					}
-				}
-			}
-			
-			memento.saveToFile(filename);
-		} catch (Exception e) {
-			if (Trace.SEVERE) {
-				Trace.trace(Trace.STRING_SEVERE, "Error saving source path info", e);
-			}
-		}
-	}
-	
-	public IClasspathAttribute[] consolidateClasspathAttributes(IClasspathAttribute[] sourceAttachmentAttributes, IClasspathAttribute[] classpathEntryAttributes) {
-		List classpathAttributeList = new ArrayList();
-		classpathAttributeList.addAll(Arrays.asList(sourceAttachmentAttributes));
-		for (int i = 0; i < classpathEntryAttributes.length; i++) {
-			boolean attributeCollision = false;
-			for (int j = 0; j < sourceAttachmentAttributes.length; j++) {
-				String name = classpathEntryAttributes[i].getName();
-				if(name != null && name.equals(sourceAttachmentAttributes[j].getName())) {
-					attributeCollision = true;
-					break;
-				}
-			}
-			if(!attributeCollision) {
-				classpathAttributeList.add(classpathEntryAttributes[i]);
-			}
-		}
-		return (IClasspathAttribute[]) classpathAttributeList.toArray(new IClasspathAttribute[classpathAttributeList.size()]);
-	}
+/*******************************************************************************
+ * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jst.server.core;
+
+import java.io.File;
+import java.util.*;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.server.core.internal.IMemento;
+import org.eclipse.jst.server.core.internal.JavaServerPlugin;
+import org.eclipse.jst.server.core.internal.RuntimeClasspathContainer;
+import org.eclipse.jst.server.core.internal.Trace;
+import org.eclipse.jst.server.core.internal.XMLMemento;
+import org.eclipse.wst.server.core.IRuntime;
+/**
+ * A runtime classpath provider provides the classpath for a Java server runtime.
+ * This provider is scoped by runtime type and may provide the classpath for multiple
+ * runtime instances.
+ * <p>
+ * This abstract class is intended to be extended only by clients
+ * to extend the <code>runtimeClasspathProviders</code> extension point.
+ * </p>
+ * <p>
+ * <b>Provisional API:</b> This class/interface is part of an interim API that is still under development and expected to 
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
+ * (repeatedly) as the API evolves.
+ * </p>
+ * 
+ * @plannedfor 3.0
+ */
+public abstract class RuntimeClasspathProviderDelegate {
+	protected class SourceAttachmentUpdate {
+		String runtimeId;
+		IPath entry;
+		IPath sourceAttachmentPath;
+		IPath sourceAttachmentRootPath;
+		IClasspathAttribute[] attributes;
+	}
+
+	private volatile List<SourceAttachmentUpdate> sourceAttachments;
+
+	private String extensionId;
+
+	private Map<String, IPath> runtimePathMap = Collections.synchronizedMap(new HashMap<String, IPath>());
+
+	private Map<String, IClasspathEntry[]> previousClasspath = Collections.synchronizedMap(new HashMap<String, IClasspathEntry[]>());
+
+	public RuntimeClasspathProviderDelegate() {
+		// default constructor
+	}
+
+	/**
+	 * Initializes this classpath provider with its life-long id.
+	 * <p>
+	 * This method is called by the framework.
+	 * Clients should never call this method.
+	 * </p>
+	 * @param id the extension id
+	 */
+	public final void initialize(String id) {
+		extensionId = id;
+	}
+
+	/**
+	 * Resolves (creates the classpath entries for) the classpath container with
+	 * the given runtime and the given classpath container id (returned from
+	 * getClasspathEntryIds()). If the classpath container cannot be resolved
+	 * (for instance, if the runtime does not exist), return null.
+	 * 
+	 * @param runtime the runtime to resolve the container for
+	 * @return an array of classpath entries for the container, or null if the
+	 *   container could not be resolved
+	 * @deprecated use resolveClasspathContainer(IProject, IRuntime) instead
+	 */
+	public IClasspathEntry[] resolveClasspathContainer(IRuntime runtime) {
+		return null;
+	}
+
+	/**
+	 * Resolves (creates the classpath entries for) the classpath container with
+	 * the given runtime and the given classpath container id (returned from
+	 * getClasspathEntryIds()). If the classpath container cannot be resolved
+	 * (for instance, if the runtime does not exist), return null.
+	 * 
+	 * @param project the project to resolve
+	 * @param runtime the runtime to resolve the container for
+	 * @return an array of classpath entries for the container, or null if the
+	 *   container could not be resolved
+	 */
+	public IClasspathEntry[] resolveClasspathContainer(IProject project, IRuntime runtime) {
+		return null;
+	}
+
+	/**
+	 * Resolve the classpath container.
+	 * 
+	 * @param runtime a runtime
+	 * @return a possibly empty array of classpath entries
+	 * @deprecated should use resolveClasspathContainerImpl(IProject, IRuntime) instead
+	 */
+	public IClasspathEntry[] resolveClasspathContainerImpl(IRuntime runtime) {
+		return resolveClasspathContainerImpl(null, runtime);
+	}
+
+	/**
+	 * Resolve the classpath container.
+	 * 
+	 * @param project a project
+	 * @param runtime a runtime
+	 * @return a possibly empty array of classpath entries
+	 */
+	public IClasspathEntry[] resolveClasspathContainerImpl(IProject project, IRuntime runtime) {
+		if (runtime == null)
+			return new IClasspathEntry[0];
+		runtimePathMap.put(runtime.getId(), runtime.getLocation());
+		IClasspathEntry[] entries = resolveClasspathContainer(project, runtime);
+		if (entries == null)
+			entries = resolveClasspathContainer(runtime);
+		
+		if (entries == null)
+			entries = new IClasspathEntry[0];
+		
+		synchronized (this) {
+			if (sourceAttachments == null)
+				load();
+		}
+		List<SourceAttachmentUpdate> srcAttachments = sourceAttachments;
+
+		if (srcAttachments != null) {
+			int size = entries.length;
+			int size2 = srcAttachments.size();
+			for (int i = 0; i < size; i++) {
+				for (int j = 0; j < size2; j++) {
+					SourceAttachmentUpdate sau = srcAttachments.get(j);
+					if (sau.runtimeId.equals(runtime.getId()) && sau.entry.equals(entries[i].getPath())) {
+						IClasspathAttribute[] consolidatedClasspathAttributes = consolidateClasspathAttributes(sau.attributes, entries[i].getExtraAttributes());
+						entries[i] = JavaCore.newLibraryEntry(entries[i].getPath(), sau.sourceAttachmentPath, sau.sourceAttachmentRootPath, entries[i].getAccessRules(), consolidatedClasspathAttributes, false);
+						break;
+					}
+				}
+			}
+		}
+		
+		String key = project.getName() + "/" + runtime.getId();
+		if (!previousClasspath.containsKey(key))
+			previousClasspath.put(key, entries);
+		else {
+			IClasspathEntry[] previousClasspathEntries = previousClasspath.get(key);
+			
+			if (previousClasspathEntries == null 
+					|| previousClasspathEntries.length != entries.length 
+					|| entriesChanged(previousClasspathEntries,entries)) {
+				if (Trace.FINEST) {
+					Trace.trace(Trace.STRING_FINEST, "Classpath update: " + key + " " + entries);
+				}
+				previousClasspath.put(key, entries);
+				
+				IPath path = new Path(RuntimeClasspathContainer.SERVER_CONTAINER);
+				path = path.append(extensionId).append(runtime.getId());
+				try {
+					IJavaProject javaProject = JavaCore.create(project);
+					JavaCore.setClasspathContainer(path, new IJavaProject[] { javaProject },
+							new IClasspathContainer[] { null }, new NullProgressMonitor());
+				} catch (Exception e) {
+					if (Trace.WARNING) {
+						Trace.trace(Trace.STRING_WARNING, "Error updating classpath", e);
+					}
+				}
+			}
+		}
+		
+		return entries;
+	}
+
+	private boolean entriesChanged(IClasspathEntry[] previousEntries, IClasspathEntry[] entries) {
+		if (previousEntries.length != entries.length) {
+			return true;
+		}
+		for (int i=0; i<previousEntries.length; i++) {
+			if ((previousEntries[i] == null && entries[i] != null)
+					|| (previousEntries[i].getPath() == null && entries[i].getPath() != null)
+					|| !previousEntries[i].getPath().equals(entries[i].getPath())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * Returns true if there are any changes in the runtime since the last time that the
+	 * classpath was resolved which may affect the classpath, and false otherwise. This
+	 * method is used to check projects when a runtime changes and automatically rebuild
+	 * them if necessary.
+	 * 
+	 * @param runtime a runtime
+	 * @return <code>true</code> if the classpath may change due to a change in the runtime,
+	 *    and <code>false</code> if there are no changes
+	 */
+	public boolean hasRuntimeClasspathChanged(IRuntime runtime) {
+		try {
+			IPath path = runtimePathMap.get(runtime.getId());
+			return (path != null && !path.equals(runtime.getLocation()));
+		} catch (Exception e) {
+			// ignore
+		}
+		return false;
+	}
+
+	private static void addJarFiles(File dir, List<IClasspathEntry> list, boolean includeSubdirectories) {
+		int depth = 0;
+		if (includeSubdirectories)
+			depth = 2;
+		addJarFiles(dir, list, depth);
+	}
+
+	private static void addJarFiles(File dir, List<IClasspathEntry> list, int depth) {
+		if (dir == null)
+			throw new IllegalArgumentException();
+		
+		File[] files = dir.listFiles();
+		if (files != null) {
+			for (File file : files) {
+				if (file.isDirectory() && depth > 0) {
+					addJarFiles(file, list, depth - 1);
+				} else if (file.getAbsolutePath().endsWith(".jar") || file.getAbsolutePath().endsWith(".zip")) {
+					IPath path = new Path(file.getAbsolutePath());
+					list.add(JavaCore.newLibraryEntry(path, null, null));
+				}
+			}
+		}
+	}
+
+	/**
+	 * Add library entries to the given list for every jar file found in the
+	 * given directory. Optionally search subdirectories as well.
+	 * 
+	 * @param list a list
+	 * @param dir a directory
+	 * @param includeSubdirectories <code>true</code> to include subdirectories, and
+	 *    <code>false</code> otherwise
+	 */
+	protected static void addLibraryEntries(List<IClasspathEntry> list, File dir, boolean includeSubdirectories) {
+		if (dir == null)
+			throw new IllegalArgumentException();
+		addJarFiles(dir, list, includeSubdirectories);
+	}
+
+	/**
+	 * Request that the classpath container for the given runtime and id be updated
+	 * with the given classpath container entries.
+	 * 
+	 * @param runtime a runtime
+	 * @param entries an array of classpath entries
+	 */
+	public void requestClasspathContainerUpdate(IRuntime runtime, IClasspathEntry[] entries) {
+		// default behaviour is to save the source path entries
+		if (runtime == null || entries == null)
+			return;
+		
+		// find the source attachments
+		List<SourceAttachmentUpdate> srcAttachments = new ArrayList<SourceAttachmentUpdate>();
+		
+		for (IClasspathEntry entry : entries) {
+			if (entry.getSourceAttachmentPath() != null || (entry.getExtraAttributes() != null && entry.getExtraAttributes().length > 0)) {
+				SourceAttachmentUpdate sau = new SourceAttachmentUpdate();
+				sau.runtimeId = runtime.getId();
+				sau.entry = entry.getPath();
+				sau.sourceAttachmentPath = entry.getSourceAttachmentPath();
+				sau.sourceAttachmentRootPath = entry.getSourceAttachmentRootPath();
+				sau.attributes = entry.getExtraAttributes();
+				srcAttachments.add(sau);
+			}
+		}
+		sourceAttachments = srcAttachments;
+		save();
+	}
+
+	/**
+	 * Load source attachment info.
+	 */
+	private void load() {
+		List<SourceAttachmentUpdate> srcAttachments = new ArrayList<SourceAttachmentUpdate>();
+		
+		String id = extensionId;
+		String filename = JavaServerPlugin.getInstance().getStateLocation().append(id + ".xml").toOSString();
+		if (!(new File(filename)).exists())
+			return;
+		
+		try {
+			IMemento memento = XMLMemento.loadMemento(filename);
+			
+			IMemento[] children = memento.getChildren("source-attachment");
+			for (IMemento child : children) {
+				try {
+					SourceAttachmentUpdate sau = new SourceAttachmentUpdate();
+					sau.runtimeId = child.getString("runtime-id");
+					String temp = child.getString("entry");
+					if (temp != null)
+						sau.entry = new Path(temp);
+					temp = child.getString("source-attachment-path");
+					if (temp != null)
+						sau.sourceAttachmentPath = new Path(temp);
+					temp = child.getString("source-attachment-root-path");
+					if (temp != null)
+						sau.sourceAttachmentRootPath = new Path(temp);
+					IMemento[] attrChildren = child.getChildren("attribute");
+					if (attrChildren != null) {
+						int size2 = attrChildren.length;
+						sau.attributes = new IClasspathAttribute[size2];
+						for (int j = 0; j < size2; j++) {
+							String name = attrChildren[j].getString("name");
+							String value = attrChildren[j].getString("value");
+							sau.attributes[j] = JavaCore.newClasspathAttribute(name, value);
+						}
+					}
+					srcAttachments.add(sau);
+				} catch (Exception e) {
+					if (Trace.WARNING) {
+						Trace.trace(Trace.STRING_WARNING, "Could not load source attachment: " + e);
+					}
+				}
+			}
+		} catch (Exception e) {
+			if (Trace.WARNING) {
+				Trace.trace(Trace.STRING_WARNING, "Could not load source path info", e);
+			}
+		}
+		sourceAttachments = srcAttachments;
+	}
+
+	/**
+	 * Save source attachment info.
+	 */
+	private synchronized void save() {
+		List<SourceAttachmentUpdate> srcAttachments = sourceAttachments;
+		if (srcAttachments == null)
+			return;
+		String id = extensionId;
+		String filename = JavaServerPlugin.getInstance().getStateLocation().append(id + ".xml").toOSString();
+		try {
+			XMLMemento memento = XMLMemento.createWriteRoot("classpath");
+
+			Iterator iterator = srcAttachments.iterator();
+			while (iterator.hasNext()) {
+				SourceAttachmentUpdate sau = (SourceAttachmentUpdate) iterator.next();
+				IMemento child = memento.createChild("source-attachment");
+				child.putString("runtime-id", sau.runtimeId);
+				if (sau.entry != null)
+					child.putString("entry", sau.entry.toPortableString());
+				if (sau.sourceAttachmentPath != null)
+					child.putString("source-attachment-path", sau.sourceAttachmentPath.toPortableString());
+				if (sau.sourceAttachmentRootPath != null)
+					child.putString("source-attachment-root-path", sau.sourceAttachmentRootPath.toPortableString());
+				if (sau.attributes != null) {
+					for (IClasspathAttribute attr : sau.attributes) {
+						IMemento attrChild = child.createChild("attribute");
+						attrChild.putString("name", attr.getName());
+						attrChild.putString("value", attr.getValue());
+					}
+				}
+			}
+			
+			memento.saveToFile(filename);
+		} catch (Exception e) {
+			if (Trace.SEVERE) {
+				Trace.trace(Trace.STRING_SEVERE, "Error saving source path info", e);
+			}
+		}
+	}
+	
+	public IClasspathAttribute[] consolidateClasspathAttributes(IClasspathAttribute[] sourceAttachmentAttributes, IClasspathAttribute[] classpathEntryAttributes) {
+		List classpathAttributeList = new ArrayList();
+		classpathAttributeList.addAll(Arrays.asList(sourceAttachmentAttributes));
+		for (int i = 0; i < classpathEntryAttributes.length; i++) {
+			boolean attributeCollision = false;
+			for (int j = 0; j < sourceAttachmentAttributes.length; j++) {
+				String name = classpathEntryAttributes[i].getName();
+				if(name != null && name.equals(sourceAttachmentAttributes[j].getName())) {
+					attributeCollision = true;
+					break;
+				}
+			}
+			if(!attributeCollision) {
+				classpathAttributeList.add(classpathEntryAttributes[i]);
+			}
+		}
+		return (IClasspathAttribute[]) classpathAttributeList.toArray(new IClasspathAttribute[classpathAttributeList.size()]);
+	}
 }
\ No newline at end of file
