diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
index 1fc2d9b..0bccea5 100644
--- a/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
+++ b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
@@ -203,6 +203,7 @@
     catEngine = catEmbedded.createEngine();
     catEngine.setName("gwt");
     catEngine.setDefaultHost("localhost");
+    catEngine.setParentClassLoader(this.getClass().getClassLoader());
 
     // It answers localhost requests.
     //
@@ -363,7 +364,7 @@
    */
   private Map<String, Resource> getResourcesFor(TreeLogger logger,
       String tomcatEtcDir) throws URISyntaxException, IOException {
-    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+    ClassLoader contextClassLoader = this.getClass().getClassLoader();
     URL url = contextClassLoader.getResource(tomcatEtcDir);
     if (url == null) {
       return null;
diff --git a/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java b/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java
index 465fbb0..f9c5ee0 100644
--- a/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java
+++ b/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+// Modified by Google.
 
 package org.apache.catalina.loader;
 
@@ -731,10 +731,10 @@
         if (getJarPath() != null) {
 
             try {
-                NamingEnumeration enum = resources.listBindings(getJarPath());
+                NamingEnumeration enum_ = resources.listBindings(getJarPath());
                 int i = 0;
-                while (enum.hasMoreElements() && (i < length)) {
-                    NameClassPair ncPair = (NameClassPair) enum.nextElement();
+                while (enum_.hasMoreElements() && (i < length)) {
+                    NameClassPair ncPair = (NameClassPair) enum_.nextElement();
                     String name = ncPair.getName();
                     // Ignore non JARs present in the lib folder
                     if (!name.endsWith(".jar"))
@@ -747,10 +747,10 @@
                     }
                     i++;
                 }
-                if (enum.hasMoreElements()) {
-                    while (enum.hasMoreElements()) {
+                if (enum_.hasMoreElements()) {
+                    while (enum_.hasMoreElements()) {
                         NameClassPair ncPair = 
-                            (NameClassPair) enum.nextElement();
+                            (NameClassPair) enum_.nextElement();
                         String name = ncPair.getName();
                         // Additional non-JAR files are allowed
                         if (name.endsWith(".jar")) {
@@ -1251,13 +1251,16 @@
 
         // (0.2) Try loading the class with the system class loader, to prevent
         //       the webapp from overriding J2SE classes
+        // GOOGLE: use the bootstrap loader, not the system loader; it breaks
+        //       embedding.
         try {
-            clazz = system.loadClass(name);
-            if (clazz != null) {
-                if (resolve)
-                    resolveClass(clazz);
-                return (clazz);
-            }
+            // clazz = system.loadClass(name);
+             clazz = Class.forName(name, false, null);
+             if (clazz != null) {
+                 if (resolve)
+                     resolveClass(clazz);
+                 return (clazz);
+             }
         } catch (ClassNotFoundException e) {
             // Ignore
         }
@@ -2162,4 +2165,3 @@
     }
 
 }
-
diff --git a/dev/core/src/org/apache/catalina/loader/WebappLoader.java b/dev/core/src/org/apache/catalina/loader/WebappLoader.java
deleted file mode 100644
index a38aeba..0000000
--- a/dev/core/src/org/apache/catalina/loader/WebappLoader.java
+++ /dev/null
@@ -1,1238 +0,0 @@
-/*
- * Copyright 1999,2004 The Apache Software Foundation.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-// Modified by Google
-package org.apache.catalina.loader;
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FilePermission;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLStreamHandlerFactory;
-import java.util.ArrayList;
-import java.util.jar.JarFile;
-
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.naming.Binding;
-import javax.naming.NameClassPair;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-import javax.servlet.ServletContext;
-
-import org.apache.catalina.Container;
-import org.apache.catalina.Context;
-import org.apache.catalina.DefaultContext;
-import org.apache.catalina.Engine;
-import org.apache.catalina.Globals;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Loader;
-import org.apache.catalina.Logger;
-import org.apache.catalina.core.StandardContext;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.catalina.util.StringManager;
-import org.apache.commons.modeler.Registry;
-import org.apache.naming.resources.DirContextURLStreamHandler;
-import org.apache.naming.resources.DirContextURLStreamHandlerFactory;
-import org.apache.naming.resources.Resource;
-
-/**
- * Classloader implementation which is specialized for handling web applications
- * in the most efficient way, while being Catalina aware (all accesses to
- * resources are made through the DirContext interface). This class loader
- * supports detection of modified Java classes, which can be used to implement
- * auto-reload support.
- * <p>
- * This class loader is configured by adding the pathnames of directories, JAR
- * files, and ZIP files with the <code>addRepository()</code> method, prior to
- * calling <code>start()</code>. When a new class is required, these
- * repositories will be consulted first to locate the class. If it is not
- * present, the system class loader will be used instead.
- * 
- * @author Craig R. McClanahan
- * @author Remy Maucherat
- * @version $Revision: 1.27 $ $Date: 2004/03/02 12:31:57 $
- */
-
-public class WebappLoader implements Lifecycle, Loader, PropertyChangeListener,
-    MBeanRegistration {
-
-  // ----------------------------------------------------------- Constructors
-
-  /**
-   * Construct a new WebappLoader with no defined parent class loader (so that
-   * the actual parent will be the system class loader).
-   */
-  public WebappLoader() {
-
-    this(null);
-
-  }
-
-  /**
-   * Construct a new WebappLoader with the specified class loader to be defined
-   * as the parent of the ClassLoader we ultimately create.
-   * 
-   * @param parent The parent class loader
-   */
-  public WebappLoader(ClassLoader parent) {
-    super();
-    this.parentClassLoader = parent;
-  }
-
-  // ----------------------------------------------------- Instance Variables
-
-  /**
-   * First load of the class.
-   */
-  private static boolean first = true;
-
-  /**
-   * The class loader being managed by this Loader component.
-   */
-  private WebappClassLoader classLoader = null;
-
-  /**
-   * The Container with which this Loader has been associated.
-   */
-  private Container container = null;
-
-  /**
-   * The debugging detail level for this component.
-   */
-  private int debug = 0;
-
-  /**
-   * The DefaultContext with which this Loader is associated.
-   */
-  protected DefaultContext defaultContext = null;
-
-  /**
-   * The "follow standard delegation model" flag that will be used to configure
-   * our ClassLoader.
-   */
-  private boolean delegate = false;
-
-  /**
-   * The descriptive information about this Loader implementation.
-   */
-  private static final String info = "org.apache.catalina.loader.WebappLoader/1.0";
-
-  /**
-   * The lifecycle event support for this component.
-   */
-  protected LifecycleSupport lifecycle = new LifecycleSupport(this);
-
-  /**
-   * The Java class name of the ClassLoader implementation to be used. This
-   * class should extend WebappClassLoader, otherwise, a different loader
-   * implementation must be used.
-   */
-  private String loaderClass = "org.apache.catalina.loader.WebappClassLoader";
-
-  /**
-   * The parent class loader of the class loader we will create.
-   */
-  private ClassLoader parentClassLoader = null;
-
-  /**
-   * The reloadable flag for this Loader.
-   */
-  private boolean reloadable = false;
-
-  /**
-   * The set of repositories associated with this class loader.
-   */
-  private String repositories[] = new String[0];
-
-  /**
-   * The string manager for this package.
-   */
-  protected static final StringManager sm = StringManager.getManager(Constants.Package);
-
-  /**
-   * Has this component been started?
-   */
-  private boolean started = false;
-
-  /**
-   * The property change support for this component.
-   */
-  protected PropertyChangeSupport support = new PropertyChangeSupport(this);
-
-  /**
-   * Classpath set in the loader.
-   */
-  private String classpath = null;
-
-  /**
-   * Repositories that are set in the loader, for JMX. GOOGLE: Added type
-   * information.
-   */
-  private ArrayList<String> loaderRepositories = null;
-
-  // ------------------------------------------------------------- Properties
-
-  /**
-   * Return the Java class loader to be used by this Container.
-   */
-  public ClassLoader getClassLoader() {
-
-    /*
-     * GOOGLE: When tomcat is embedded (as we are doing), classLoader is always
-     * null. Returning the parentClassLoader seems to do the right thing.
-     */
-    if (classLoader != null) {
-      return classLoader;
-    } else {
-      return parentClassLoader;
-    }
-
-  }
-
-  /**
-   * Return the Container with which this Logger has been associated.
-   */
-  public Container getContainer() {
-
-    return (container);
-
-  }
-
-  /**
-   * Set the Container with which this Logger has been associated.
-   * 
-   * @param container The associated Container
-   */
-  public void setContainer(Container container) {
-
-    // Deregister from the old Container (if any)
-    if ((this.container != null) && (this.container instanceof Context))
-      ((Context) this.container).removePropertyChangeListener(this);
-
-    // Process this property change
-    Container oldContainer = this.container;
-    this.container = container;
-    support.firePropertyChange("container", oldContainer, this.container);
-
-    // Register with the new Container (if any)
-    if ((this.container != null) && (this.container instanceof Context)) {
-      setReloadable(((Context) this.container).getReloadable());
-      ((Context) this.container).addPropertyChangeListener(this);
-    }
-
-  }
-
-  /**
-   * Return the DefaultContext with which this Loader is associated. XXX What is
-   * that ???
-   */
-  public DefaultContext getDefaultContext() {
-
-    return (this.defaultContext);
-
-  }
-
-  /**
-   * Set the DefaultContext with which this Loader is associated.
-   * 
-   * @param defaultContext The newly associated DefaultContext
-   */
-  public void setDefaultContext(DefaultContext defaultContext) {
-
-    DefaultContext oldDefaultContext = this.defaultContext;
-    this.defaultContext = defaultContext;
-    support.firePropertyChange("defaultContext", oldDefaultContext,
-        this.defaultContext);
-
-  }
-
-  /**
-   * Return the debugging detail level for this component.
-   */
-  public int getDebug() {
-
-    return (this.debug);
-
-  }
-
-  /**
-   * Set the debugging detail level for this component.
-   * 
-   * @param debug The new debugging detail level
-   */
-  public void setDebug(int debug) {
-
-    int oldDebug = this.debug;
-    this.debug = debug;
-    support.firePropertyChange("debug", new Integer(oldDebug), new Integer(
-        this.debug));
-
-  }
-
-  /**
-   * Return the "follow standard delegation model" flag used to configure our
-   * ClassLoader.
-   */
-  public boolean getDelegate() {
-
-    return (this.delegate);
-
-  }
-
-  /**
-   * Set the "follow standard delegation model" flag used to configure our
-   * ClassLoader.
-   * 
-   * @param delegate The new flag
-   */
-  public void setDelegate(boolean delegate) {
-
-    boolean oldDelegate = this.delegate;
-    this.delegate = delegate;
-    support.firePropertyChange("delegate", new Boolean(oldDelegate),
-        new Boolean(this.delegate));
-
-  }
-
-  /**
-   * Return descriptive information about this Loader implementation and the
-   * corresponding version number, in the format
-   * <code>&lt;description&gt;/&lt;version&gt;</code>.
-   */
-  public String getInfo() {
-
-    return (info);
-
-  }
-
-  /**
-   * Return the ClassLoader class name.
-   */
-  public String getLoaderClass() {
-
-    return (this.loaderClass);
-
-  }
-
-  /**
-   * Set the ClassLoader class name.
-   * 
-   * @param loaderClass The new ClassLoader class name
-   */
-  public void setLoaderClass(String loaderClass) {
-
-    this.loaderClass = loaderClass;
-
-  }
-
-  /**
-   * Return the reloadable flag for this Loader.
-   */
-  public boolean getReloadable() {
-
-    return (this.reloadable);
-
-  }
-
-  /**
-   * Set the reloadable flag for this Loader.
-   * 
-   * @param reloadable The new reloadable flag
-   */
-  public void setReloadable(boolean reloadable) {
-
-    // Process this property change
-    boolean oldReloadable = this.reloadable;
-    this.reloadable = reloadable;
-    support.firePropertyChange("reloadable", new Boolean(oldReloadable),
-        new Boolean(this.reloadable));
-
-  }
-
-  // --------------------------------------------------------- Public Methods
-
-  /**
-   * Add a property change listener to this component.
-   * 
-   * @param listener The listener to add
-   */
-  public void addPropertyChangeListener(PropertyChangeListener listener) {
-
-    support.addPropertyChangeListener(listener);
-
-  }
-
-  /**
-   * Add a new repository to the set of repositories for this class loader.
-   * 
-   * @param repository Repository to be added
-   */
-  public void addRepository(String repository) {
-
-    if (log.isDebugEnabled())
-      log.debug(sm.getString("webappLoader.addRepository", repository));
-
-    for (int i = 0; i < repositories.length; i++) {
-      if (repository.equals(repositories[i]))
-        return;
-    }
-    String results[] = new String[repositories.length + 1];
-    for (int i = 0; i < repositories.length; i++)
-      results[i] = repositories[i];
-    results[repositories.length] = repository;
-    repositories = results;
-
-    if (started && (classLoader != null)) {
-      classLoader.addRepository(repository);
-      if (loaderRepositories != null)
-        loaderRepositories.add(repository);
-      setClassPath();
-    }
-
-  }
-
-  /**
-   * Return the set of repositories defined for this class loader. If none are
-   * defined, a zero-length array is returned. For security reason, returns a
-   * clone of the Array (since String are immutable).
-   */
-  public String[] findRepositories() {
-
-    return ((String[]) repositories.clone());
-
-  }
-
-  public String[] getRepositories() {
-    return ((String[]) repositories.clone());
-  }
-
-  /**
-   * Extra repositories for this loader
-   */
-  public String getRepositoriesString() {
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < repositories.length; i++) {
-      sb.append(repositories[i]).append(":");
-    }
-    return sb.toString();
-  }
-
-  public String[] getLoaderRepositories() {
-    if (loaderRepositories == null)
-      return null;
-    String res[] = new String[loaderRepositories.size()];
-    loaderRepositories.toArray(res);
-    return res;
-  }
-
-  public String getLoaderRepositoriesString() {
-    String repositories[] = getLoaderRepositories();
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < repositories.length; i++) {
-      sb.append(repositories[i]).append(":");
-    }
-    return sb.toString();
-  }
-
-  /**
-   * Classpath, as set in org.apache.catalina.jsp_classpath context property
-   * 
-   * @return The classpath
-   */
-  public String getClasspath() {
-    return classpath;
-  }
-
-  /**
-   * Has the internal repository associated with this Loader been modified, such
-   * that the loaded classes should be reloaded?
-   */
-  public boolean modified() {
-
-    return (classLoader.modified());
-
-  }
-
-  /**
-   * Used to periodically signal to the classloader to release JAR resources.
-   */
-  public void closeJARs(boolean force) {
-    if (classLoader != null) {
-      classLoader.closeJARs(force);
-    }
-  }
-
-  /**
-   * Remove a property change listener from this component.
-   * 
-   * @param listener The listener to remove
-   */
-  public void removePropertyChangeListener(PropertyChangeListener listener) {
-
-    support.removePropertyChangeListener(listener);
-
-  }
-
-  /**
-   * Return a String representation of this component.
-   */
-  public String toString() {
-
-    StringBuffer sb = new StringBuffer("WebappLoader[");
-    if (container != null)
-      sb.append(container.getName());
-    sb.append("]");
-    return (sb.toString());
-
-  }
-
-  // ------------------------------------------------------ Lifecycle Methods
-
-  /**
-   * Add a lifecycle event listener to this component.
-   * 
-   * @param listener The listener to add
-   */
-  public void addLifecycleListener(LifecycleListener listener) {
-
-    lifecycle.addLifecycleListener(listener);
-
-  }
-
-  /**
-   * Get the lifecycle listeners associated with this lifecycle. If this
-   * Lifecycle has no listeners registered, a zero-length array is returned.
-   */
-  public LifecycleListener[] findLifecycleListeners() {
-
-    return lifecycle.findLifecycleListeners();
-
-  }
-
-  /**
-   * Remove a lifecycle event listener from this component.
-   * 
-   * @param listener The listener to remove
-   */
-  public void removeLifecycleListener(LifecycleListener listener) {
-
-    lifecycle.removeLifecycleListener(listener);
-
-  }
-
-  private boolean initialized = false;
-
-  public void init() {
-    initialized = true;
-
-    if (oname == null) {
-      // not registered yet - standalone or API
-      if (container instanceof StandardContext) {
-        // Register ourself. The container must be a webapp
-        try {
-          StandardContext ctx = (StandardContext) container;
-          Engine eng = (Engine) ctx.getParent().getParent();
-          String path = ctx.getPath();
-          if (path.equals("")) {
-            path = "/";
-          }
-          oname = new ObjectName(ctx.getEngineName() + ":type=Loader,path="
-              + path + ",host=" + ctx.getParent().getName());
-          Registry.getRegistry(null, null).registerComponent(this, oname, null);
-          controller = oname;
-        } catch (Exception e) {
-          log.error("Error registering loader", e);
-        }
-      }
-    }
-
-    if (container == null) {
-      // JMX created the loader
-      // TODO
-
-    }
-  }
-
-  public void destroy() {
-    if (controller == oname) {
-      // Self-registration, undo it
-      Registry.getRegistry(null, null).unregisterComponent(oname);
-      oname = null;
-    }
-    initialized = false;
-
-  }
-
-  /**
-   * Start this component, initializing our associated class loader.
-   * 
-   * @exception LifecycleException if a lifecycle error occurs
-   */
-  public void start() throws LifecycleException {
-    // Validate and update our current component state
-    if (!initialized)
-      init();
-    if (started)
-      throw new LifecycleException(sm.getString("webappLoader.alreadyStarted"));
-    if (log.isDebugEnabled())
-      log.debug(sm.getString("webappLoader.starting"));
-    lifecycle.fireLifecycleEvent(START_EVENT, null);
-    started = true;
-
-    if (container.getResources() == null) {
-      log.info("No resources for " + container);
-      return;
-    }
-    // Register a stream handler factory for the JNDI protocol
-    URLStreamHandlerFactory streamHandlerFactory = new DirContextURLStreamHandlerFactory();
-    if (first) {
-      first = false;
-      try {
-        URL.setURLStreamHandlerFactory(streamHandlerFactory);
-      } catch (Exception e) {
-        // Log and continue anyway, this is not critical
-        log.error("Error registering jndi stream handler", e);
-      } catch (Throwable t) {
-        // This is likely a dual registration
-        log.info("Dual registration of jndi stream handler: " + t.getMessage());
-      }
-    }
-
-    // Construct a class loader based on our current repositories list
-    try {
-
-      classLoader = createClassLoader();
-      classLoader.setResources(container.getResources());
-      classLoader.setDebug(this.debug);
-      classLoader.setDelegate(this.delegate);
-
-      for (int i = 0; i < repositories.length; i++) {
-        classLoader.addRepository(repositories[i]);
-      }
-
-      // Configure our repositories
-      setRepositories();
-      setClassPath();
-
-      setPermissions();
-
-      if (classLoader instanceof Lifecycle)
-        ((Lifecycle) classLoader).start();
-
-      // Binding the Webapp class loader to the directory context
-      DirContextURLStreamHandler.bind((ClassLoader) classLoader,
-          this.container.getResources());
-
-      StandardContext ctx = (StandardContext) container;
-      Engine eng = (Engine) ctx.getParent().getParent();
-      String path = ctx.getPath();
-      if (path.equals("")) {
-        path = "/";
-      }
-      ObjectName cloname = new ObjectName(ctx.getEngineName()
-          + ":type=WebappClassLoader,path=" + path + ",host="
-          + ctx.getParent().getName());
-      Registry.getRegistry(null, null).registerComponent(classLoader, cloname,
-          null);
-
-    } catch (Throwable t) {
-      log.error("LifecycleException ", t);
-      throw new LifecycleException("start: ", t);
-    }
-
-  }
-
-  /**
-   * Stop this component, finalizing our associated class loader.
-   * 
-   * @exception LifecycleException if a lifecycle error occurs
-   */
-  public void stop() throws LifecycleException {
-
-    // Validate and update our current component state
-    if (!started)
-      throw new LifecycleException(sm.getString("webappLoader.notStarted"));
-    if (log.isDebugEnabled())
-      log.debug(sm.getString("webappLoader.stopping"));
-    lifecycle.fireLifecycleEvent(STOP_EVENT, null);
-    started = false;
-
-    // Remove context attributes as appropriate
-    if (container instanceof Context) {
-      ServletContext servletContext = ((Context) container).getServletContext();
-      servletContext.removeAttribute(Globals.CLASS_PATH_ATTR);
-    }
-
-    // Throw away our current class loader
-    if (classLoader instanceof Lifecycle)
-      ((Lifecycle) classLoader).stop();
-    DirContextURLStreamHandler.unbind((ClassLoader) classLoader);
-
-    try {
-      StandardContext ctx = (StandardContext) container;
-      Engine eng = (Engine) ctx.getParent().getParent();
-      String path = ctx.getPath();
-      if (path.equals("")) {
-        path = "/";
-      }
-      ObjectName cloname = new ObjectName(ctx.getEngineName()
-          + ":type=WebappClassLoader,path=" + path + ",host="
-          + ctx.getParent().getName());
-      Registry.getRegistry(null, null).unregisterComponent(cloname);
-    } catch (Throwable t) {
-      log.error("LifecycleException ", t);
-    }
-
-    classLoader = null;
-
-    destroy();
-
-  }
-
-  // ----------------------------------------- PropertyChangeListener Methods
-
-  /**
-   * Process property change events from our associated Context.
-   * 
-   * @param event The property change event that has occurred
-   */
-  public void propertyChange(PropertyChangeEvent event) {
-
-    // Validate the source of this event
-    if (!(event.getSource() instanceof Context))
-      return;
-    Context context = (Context) event.getSource();
-
-    // Process a relevant property change
-    if (event.getPropertyName().equals("reloadable")) {
-      try {
-        setReloadable(((Boolean) event.getNewValue()).booleanValue());
-      } catch (NumberFormatException e) {
-        log.error(sm.getString("webappLoader.reloadable",
-            event.getNewValue().toString()));
-      }
-    }
-
-  }
-
-  // ------------------------------------------------------- Private Methods
-
-  /**
-   * Create associated classLoader. GOOGLE: Added type information.
-   */
-  private WebappClassLoader createClassLoader() throws Exception {
-
-    Class<?> clazz = Class.forName(loaderClass);
-    WebappClassLoader classLoader = null;
-
-    if (parentClassLoader == null) {
-      parentClassLoader = Thread.currentThread().getContextClassLoader();
-    }
-    Class<?>[] argTypes = {ClassLoader.class};
-    Object[] args = {parentClassLoader};
-    Constructor<?> constr = clazz.getConstructor(argTypes);
-    classLoader = (WebappClassLoader) constr.newInstance(args);
-
-    return classLoader;
-
-  }
-
-  /**
-   * Log a message on the Logger associated with our Container (if any)
-   * 
-   * @param message Message to be logged
-   */
-  private void log(String message) {
-
-    Logger logger = null;
-    if (container != null)
-      logger = container.getLogger();
-    if (logger != null)
-      logger.log("WebappLoader[" + container.getName() + "]: " + message);
-    else {
-      String containerName = null;
-      if (container != null)
-        containerName = container.getName();
-      System.out.println("WebappLoader[" + containerName + "]: " + message);
-    }
-
-  }
-
-  /**
-   * Log a message on the Logger associated with our Container (if any)
-   * 
-   * @param message Message to be logged
-   * @param throwable Associated exception
-   */
-  private void log(String message, Throwable throwable) {
-
-    Logger logger = null;
-    if (container != null)
-      logger = container.getLogger();
-    if (logger != null) {
-      logger.log("WebappLoader[" + container.getName() + "] " + message,
-          throwable);
-    } else {
-      String containerName = null;
-      if (container != null)
-        containerName = container.getName();
-      System.out.println("WebappLoader[" + containerName + "]: " + message);
-      System.out.println("" + throwable);
-      throwable.printStackTrace(System.out);
-    }
-
-  }
-
-  /**
-   * Configure associated class loader permissions.
-   */
-  private void setPermissions() {
-
-    if (System.getSecurityManager() == null)
-      return;
-    if (!(container instanceof Context))
-      return;
-
-    // Tell the class loader the root of the context
-    ServletContext servletContext = ((Context) container).getServletContext();
-
-    // Assigning permissions for the work directory
-    File workDir = (File) servletContext.getAttribute(Globals.WORK_DIR_ATTR);
-    if (workDir != null) {
-      try {
-        String workDirPath = workDir.getCanonicalPath();
-        classLoader.addPermission(new FilePermission(workDirPath, "read,write"));
-        classLoader.addPermission(new FilePermission(workDirPath
-            + File.separator + "-", "read,write,delete"));
-      } catch (IOException e) {
-        // Ignore
-      }
-    }
-
-    try {
-
-      URL rootURL = servletContext.getResource("/");
-      classLoader.addPermission(rootURL);
-
-      String contextRoot = servletContext.getRealPath("/");
-      if (contextRoot != null) {
-        try {
-          contextRoot = (new File(contextRoot)).getCanonicalPath();
-          classLoader.addPermission(contextRoot);
-        } catch (IOException e) {
-          // Ignore
-        }
-      }
-
-      URL classesURL = servletContext.getResource("/WEB-INF/classes/");
-      classLoader.addPermission(classesURL);
-      URL libURL = servletContext.getResource("/WEB-INF/lib/");
-      classLoader.addPermission(libURL);
-
-      if (contextRoot != null) {
-
-        if (libURL != null) {
-          File rootDir = new File(contextRoot);
-          File libDir = new File(rootDir, "WEB-INF/lib/");
-          try {
-            String path = libDir.getCanonicalPath();
-            classLoader.addPermission(path);
-          } catch (IOException e) {
-          }
-        }
-
-      } else {
-
-        if (workDir != null) {
-          if (libURL != null) {
-            File libDir = new File(workDir, "WEB-INF/lib/");
-            try {
-              String path = libDir.getCanonicalPath();
-              classLoader.addPermission(path);
-            } catch (IOException e) {
-            }
-          }
-          if (classesURL != null) {
-            File classesDir = new File(workDir, "WEB-INF/classes/");
-            try {
-              String path = classesDir.getCanonicalPath();
-              classLoader.addPermission(path);
-            } catch (IOException e) {
-            }
-          }
-        }
-
-      }
-
-    } catch (MalformedURLException e) {
-    }
-
-  }
-
-  /**
-   * Configure the repositories for our class loader, based on the associated
-   * Context. GOOGLE: Added type information.
-   */
-  private void setRepositories() {
-
-    if (!(container instanceof Context))
-      return;
-    ServletContext servletContext = ((Context) container).getServletContext();
-    if (servletContext == null)
-      return;
-
-    loaderRepositories = new ArrayList<String>();
-    // Loading the work directory
-    File workDir = (File) servletContext.getAttribute(Globals.WORK_DIR_ATTR);
-    if (workDir == null) {
-      log.info("No work dir for " + servletContext);
-    }
-
-    if (log.isDebugEnabled())
-      log.debug(sm.getString("webappLoader.deploy", workDir.getAbsolutePath()));
-
-    classLoader.setWorkDir(workDir);
-
-    DirContext resources = container.getResources();
-
-    // Setting up the class repository (/WEB-INF/classes), if it exists
-
-    String classesPath = "/WEB-INF/classes";
-    DirContext classes = null;
-
-    try {
-      Object object = resources.lookup(classesPath);
-      if (object instanceof DirContext) {
-        classes = (DirContext) object;
-      }
-    } catch (NamingException e) {
-      // Silent catch: it's valid that no /WEB-INF/classes collection
-      // exists
-    }
-
-    if (classes != null) {
-
-      File classRepository = null;
-
-      String absoluteClassesPath = servletContext.getRealPath(classesPath);
-
-      if (absoluteClassesPath != null) {
-
-        classRepository = new File(absoluteClassesPath);
-
-      } else {
-
-        classRepository = new File(workDir, classesPath);
-        classRepository.mkdirs();
-        copyDir(classes, classRepository);
-
-      }
-
-      if (log.isDebugEnabled())
-        log.debug(sm.getString("webappLoader.classDeploy", classesPath,
-            classRepository.getAbsolutePath()));
-
-      // Adding the repository to the class loader
-      classLoader.addRepository(classesPath + "/", classRepository);
-      loaderRepositories.add(classesPath + "/");
-
-    }
-
-    // Setting up the JAR repository (/WEB-INF/lib), if it exists
-
-    String libPath = "/WEB-INF/lib";
-
-    classLoader.setJarPath(libPath);
-
-    DirContext libDir = null;
-    // Looking up directory /WEB-INF/lib in the context
-    try {
-      Object object = resources.lookup(libPath);
-      if (object instanceof DirContext)
-        libDir = (DirContext) object;
-    } catch (NamingException e) {
-      // Silent catch: it's valid that no /WEB-INF/lib collection
-      // exists
-    }
-
-    if (libDir != null) {
-
-      boolean copyJars = false;
-      String absoluteLibPath = servletContext.getRealPath(libPath);
-
-      File destDir = null;
-
-      if (absoluteLibPath != null) {
-        destDir = new File(absoluteLibPath);
-      } else {
-        copyJars = true;
-        destDir = new File(workDir, libPath);
-        destDir.mkdirs();
-      }
-
-      // Looking up directory /WEB-INF/lib in the context
-      try {
-        // GOOGLE: "enum" is a reserved word in JDK 1.5
-        NamingEnumeration<Binding> enum_ = resources.listBindings(libPath);
-        while (enum_.hasMoreElements()) {
-
-          Binding binding = enum_.nextElement();
-          String filename = libPath + "/" + binding.getName();
-          if (!filename.endsWith(".jar"))
-            continue;
-
-          // Copy JAR in the work directory, always (the JAR file
-          // would get locked otherwise, which would make it
-          // impossible to update it or remove it at runtime)
-          File destFile = new File(destDir, binding.getName());
-
-          if (log.isDebugEnabled())
-            log.debug(sm.getString("webappLoader.jarDeploy", filename,
-                destFile.getAbsolutePath()));
-
-          Resource jarResource = (Resource) binding.getObject();
-          if (copyJars) {
-            if (!copy(jarResource.streamContent(), new FileOutputStream(
-                destFile)))
-              continue;
-          }
-
-          try {
-            JarFile jarFile = new JarFile(destFile);
-            classLoader.addJar(filename, jarFile, destFile);
-          } catch (Exception ex) {
-            // Catch the exception if there is an empty jar file
-            // Should ignore and continute loading other jar files
-            // in the dir
-          }
-
-          loaderRepositories.add(filename);
-
-        }
-      } catch (NamingException e) {
-        // Silent catch: it's valid that no /WEB-INF/lib directory
-        // exists
-      } catch (IOException e) {
-        e.printStackTrace();
-      }
-
-    }
-
-  }
-
-  /**
-   * Set the appropriate context attribute for our class path. This is required
-   * only because Jasper depends on it.
-   */
-  private void setClassPath() {
-
-    // Validate our current state information
-    if (!(container instanceof Context))
-      return;
-    ServletContext servletContext = ((Context) container).getServletContext();
-    if (servletContext == null)
-      return;
-
-    if (container instanceof StandardContext) {
-      String baseClasspath = ((StandardContext) container).getCompilerClasspath();
-      if (baseClasspath != null) {
-        servletContext.setAttribute(Globals.CLASS_PATH_ATTR, baseClasspath);
-        return;
-      }
-    }
-
-    StringBuffer classpath = new StringBuffer();
-
-    // Assemble the class path information from our class loader chain
-    ClassLoader loader = getClassLoader();
-    int layers = 0;
-    int n = 0;
-    while (loader != null) {
-      if (!(loader instanceof URLClassLoader)) {
-        String cp = getClasspath(loader);
-        if (cp == null) {
-          log.info("Unknown loader " + loader + " " + loader.getClass());
-          break;
-        } else {
-          if (n > 0)
-            classpath.append(File.pathSeparator);
-          classpath.append(cp);
-          n++;
-        }
-        break;
-        // continue;
-      }
-      URL repositories[] = ((URLClassLoader) loader).getURLs();
-      for (int i = 0; i < repositories.length; i++) {
-        String repository = repositories[i].toString();
-        if (repository.startsWith("file://"))
-          repository = repository.substring(7);
-        else if (repository.startsWith("file:"))
-          repository = repository.substring(5);
-        else if (repository.startsWith("jndi:"))
-          repository = servletContext.getRealPath(repository.substring(5));
-        else
-          continue;
-        if (repository == null)
-          continue;
-        if (n > 0)
-          classpath.append(File.pathSeparator);
-        classpath.append(repository);
-        n++;
-      }
-      loader = loader.getParent();
-      layers++;
-    }
-
-    this.classpath = classpath.toString();
-
-    // Store the assembled class path as a servlet context attribute
-    servletContext.setAttribute(Globals.CLASS_PATH_ATTR, classpath.toString());
-
-  }
-
-  // try to extract the classpath from a loader that is not URLClassLoader
-  private String getClasspath(ClassLoader loader) {
-    try {
-      Method m = loader.getClass().getMethod("getClasspath", new Class[] {});
-      if (log.isTraceEnabled())
-        log.trace("getClasspath " + m);
-      if (m == null)
-        return null;
-      Object o = m.invoke(loader, new Object[] {});
-      if (log.isDebugEnabled())
-        log.debug("gotClasspath " + o);
-      if (o instanceof String)
-        return (String) o;
-      return null;
-    } catch (Exception ex) {
-      if (log.isDebugEnabled())
-        log.debug("getClasspath ", ex);
-    }
-    return null;
-  }
-
-  /**
-   * Copy directory.
-   */
-  private boolean copyDir(DirContext srcDir, File destDir) {
-
-    try {
-
-      // GOOGLE: "enum" is a reserved word in JDK 1.5
-      NamingEnumeration<NameClassPair> enum_ = srcDir.list("");
-      while (enum_.hasMoreElements()) {
-        NameClassPair ncPair = enum_.nextElement();
-        String name = ncPair.getName();
-        Object object = srcDir.lookup(name);
-        File currentFile = new File(destDir, name);
-        if (object instanceof Resource) {
-          InputStream is = ((Resource) object).streamContent();
-          OutputStream os = new FileOutputStream(currentFile);
-          if (!copy(is, os))
-            return false;
-        } else if (object instanceof InputStream) {
-          OutputStream os = new FileOutputStream(currentFile);
-          if (!copy((InputStream) object, os))
-            return false;
-        } else if (object instanceof DirContext) {
-          currentFile.mkdir();
-          copyDir((DirContext) object, currentFile);
-        }
-      }
-
-    } catch (NamingException e) {
-      return false;
-    } catch (IOException e) {
-      return false;
-    }
-
-    return true;
-
-  }
-
-  /**
-   * Copy a file to the specified temp directory. This is required only because
-   * Jasper depends on it.
-   */
-  private boolean copy(InputStream is, OutputStream os) {
-
-    try {
-      byte[] buf = new byte[4096];
-      while (true) {
-        int len = is.read(buf);
-        if (len < 0)
-          break;
-        os.write(buf, 0, len);
-      }
-      is.close();
-      os.close();
-    } catch (IOException e) {
-      return false;
-    }
-
-    return true;
-
-  }
-
-  private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(WebappLoader.class);
-
-  private ObjectName oname;
-  private MBeanServer mserver;
-  private String domain;
-  private ObjectName controller;
-
-  public ObjectName preRegister(MBeanServer server, ObjectName name)
-      throws Exception {
-    oname = name;
-    mserver = server;
-    domain = name.getDomain();
-
-    return name;
-  }
-
-  public void postRegister(Boolean registrationDone) {
-  }
-
-  public void preDeregister() throws Exception {
-  }
-
-  public void postDeregister() {
-  }
-
-  public ObjectName getController() {
-    return controller;
-  }
-
-  public void setController(ObjectName controller) {
-    this.controller = controller;
-  }
-
-}
