diff --git a/dev/build.xml b/dev/build.xml
index 08677ef..0ea5528 100755
--- a/dev/build.xml
+++ b/dev/build.xml
@@ -34,6 +34,7 @@
       excludes="**/super/**">
       <classpath>
         <pathelement location="${javac.out}" />
+        <pathelement location="${gwt.tools.lib}/tomcat/servlet-api-2.5.jar" />
         <pathelement location="${gwt.tools.lib}/junit/junit-4.8.2.jar" />
         <pathelement location="${gwt.tools.lib}/jfreechart/jfreechart-1.0.3.jar" />
         <pathelement location="${gwt.tools.lib}/selenium/selenium-java-client-driver.jar" />
@@ -62,13 +63,33 @@
           <include name="jetty/jetty-6.1.11.jar" />
           <include name="icu4j/4.4.2/icu4j.jar" />
           <include name="protobuf/protobuf-2.2.0/protobuf-java-rebased-2.2.0.jar" />
-          <!-- dependencies needed for JSP support in DevMode: BEGIN -->
+          <include name="tomcat/ant-launcher-1.6.5.jar" />
+          <include name="tomcat/catalina-1.0.jar" />
+          <include name="tomcat/catalina-optional-1.0.jar" />
+          <include name="tomcat/commons-beanutils-1.6.jar" />
+          <include name="tomcat/commons-collections-3.1.jar" />
+          <include name="tomcat/commons-digester-1.5.jar" />
           <include name="tomcat/commons-el-1.0.jar" />
+          <include name="tomcat/commons-logging-1.0.jar" />
+          <include name="tomcat/commons-modeler-1.1.jar" />
+          <include name="tomcat/jakarta-regexp-1.3.jar" />
           <include name="tomcat/jasper-compiler-1.0.jar" />
           <include name="tomcat/jasper-runtime-1.0.jar" />
           <include name="tomcat/jsp-api-2.0.jar" />
-          <!-- dependencies needed for JSP support in DevMode: END -->
-          <include name="apache/commons/commons-collections-3.2.1.jar" />
+          <include name="tomcat/mx4j-jmx-1.1.jar" />
+          <include name="tomcat/naming-common-1.0.jar" />
+          <include name="tomcat/naming-factory-1.0.jar" />
+          <include name="tomcat/naming-java-1.0.jar" />
+          <include name="tomcat/naming-resources-1.0.jar" />
+          <include name="tomcat/servlet-api-2.5.jar" />
+          <include name="tomcat/servlet-api-2.4.jar" />
+          <include name="tomcat/servlets-common-1.0.jar" />
+          <include name="tomcat/servlets-default-1.0.jar" />
+          <include name="tomcat/servlets-invoker-1.0.jar" />
+          <include name="tomcat/tomcat-coyote-1.0.jar" />
+          <include name="tomcat/tomcat-http11-1.0.jar" />
+          <include name="tomcat/tomcat-jk2-2.1.jar" />
+          <include name="tomcat/tomcat-util-5.1.jar" />
           <!-- htmlunit dependencies not already included: BEGIN -->
           <include name="apache/http/httpclient-4.1.2.jar" />
           <include name="apache/http/httpcore-4.1.2.jar" />
@@ -110,13 +131,33 @@
           <zipfileset src="${gwt.tools.lib}/jetty/jetty-6.1.11.jar" />
           <zipfileset src="${gwt.tools.lib}/icu4j/4.4.2/icu4j.jar" />
           <zipfileset src="${gwt.tools.lib}/protobuf/protobuf-2.2.0/protobuf-java-rebased-2.2.0.jar" />
-          <!-- dependencies needed for JSP support in DevMode: BEGIN -->
+          <zipfileset src="${gwt.tools.lib}/tomcat/ant-launcher-1.6.5.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/catalina-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/catalina-optional-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/commons-beanutils-1.6.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/commons-collections-3.1.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/commons-digester-1.5.jar" />
           <zipfileset src="${gwt.tools.lib}/tomcat/commons-el-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/commons-logging-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/commons-modeler-1.1.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/jakarta-regexp-1.3.jar" />
           <zipfileset src="${gwt.tools.lib}/tomcat/jasper-compiler-1.0.jar" />
           <zipfileset src="${gwt.tools.lib}/tomcat/jasper-runtime-1.0.jar" />
           <zipfileset src="${gwt.tools.lib}/tomcat/jsp-api-2.0.jar" />
-          <!-- dependencies needed for JSP support in DevMode: END -->
-          <zipfileset src="${gwt.tools.lib}/apache/commons/commons-collections-3.2.1.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/mx4j-jmx-1.1.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/naming-common-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/naming-factory-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/naming-java-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/naming-resources-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/servlet-api-2.5.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/servlet-api-2.4.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/servlets-common-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/servlets-default-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/servlets-invoker-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-coyote-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-http11-1.0.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-jk2-2.1.jar" />
+          <zipfileset src="${gwt.tools.lib}/tomcat/tomcat-util-5.1.jar" />
           <!-- htmlunit dependencies not already included: BEGIN -->
           <zipfileset src="${gwt.tools.lib}/apache/http/httpclient-4.1.2.jar" />
           <zipfileset src="${gwt.tools.lib}/apache/http/httpcore-4.1.2.jar" />
@@ -179,7 +220,7 @@
       <classpath>
           <pathelement location="${gwt.tools.lib}/apache/ant-1.6.5.jar" />
           <pathelement location="${gwt.tools.lib}/eclipse/jdt-3.4.2_r894.jar" />
-          <pathelement location="${gwt.tools.lib}/apache/commons/commons-collections-3.2.1.jar" />
+          <pathelement location="${gwt.tools.lib}/tomcat/commons-collections-3.1.jar" />
           <pathelement location="${gwt.tools.lib}/guava/guava-10.0.1/guava-10.0.1-rebased.jar" />
           <pathelement location="${gwt.tools.lib}/jscomp/r1649/compiler-rebased.jar" />
       </classpath>
diff --git a/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java b/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java
index 914713d..7c65f6e 100644
--- a/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java
+++ b/dev/core/src/com/google/gwt/dev/CompileTaskRunner.java
@@ -63,7 +63,7 @@
         }
       });
 
-      compilerThread.setName("GWT Compiler Thread");
+      compilerThread.setName("GWTCompiler Thread");
       compilerThread.start();
       // TODO(jat): create an app frame for loggerWindow
       
diff --git a/dev/core/src/com/google/gwt/dev/GWTCompiler.java b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
new file mode 100644
index 0000000..ef2e4ea
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2008 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.dev.CompileTaskRunner.CompileTask;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.cfg.ModuleDefLoader;
+import com.google.gwt.dev.jjs.JJSOptions;
+import com.google.gwt.dev.jjs.PermutationResult;
+import com.google.gwt.dev.shell.CheckForUpdates;
+import com.google.gwt.dev.shell.CheckForUpdates.UpdateResult;
+import com.google.gwt.dev.util.FileBackedObject;
+import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.arg.ArgHandlerLocalWorkers;
+import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
+import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
+import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
+import com.google.gwt.util.tools.ToolBase;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.FutureTask;
+
+/**
+ * The main executable entry point for the GWT Java to JavaScript compiler.
+ * 
+ * @deprecated Use {@link Compiler} instead
+ */
+@Deprecated
+public class GWTCompiler {
+
+  static final class ArgProcessor extends PrecompileTaskArgProcessor {
+    public ArgProcessor(LegacyCompilerOptions options) {
+      super(options);
+
+      registerHandler(new ArgHandlerOutDir(options));
+
+      // Override the ArgHandlerWorkDirRequired in the super class.
+      registerHandler(new ArgHandlerWorkDirOptional(options));
+
+      registerHandler(new ArgHandlerLocalWorkers(options));
+    }
+
+    @Override
+    protected String getName() {
+      return GWTCompiler.class.getName();
+    }
+  }
+
+  /**
+   * Simple implementation of {@link LegacyCompilerOptions}.
+   */
+  public static class GWTCompilerOptionsImpl extends PrecompileTaskOptionsImpl
+      implements LegacyCompilerOptions {
+
+    private int localWorkers;
+    private File outDir;
+
+    public GWTCompilerOptionsImpl() {
+    }
+
+    public GWTCompilerOptionsImpl(LegacyCompilerOptions other) {
+      copyFrom(other);
+    }
+
+    public void copyFrom(LegacyCompilerOptions other) {
+      super.copyFrom(other);
+      setLocalWorkers(other.getLocalWorkers());
+      setOutDir(other.getOutDir());
+    }
+
+    @Override
+    public int getLocalWorkers() {
+      return localWorkers;
+    }
+
+    @Override
+    public File getOutDir() {
+      return outDir;
+    }
+
+    @Override
+    public void setLocalWorkers(int localWorkers) {
+      this.localWorkers = localWorkers;
+    }
+
+    @Override
+    public void setOutDir(File outDir) {
+      this.outDir = outDir;
+    }
+  }
+
+  public static void main(String[] args) {
+    ToolBase.legacyWarn(GWTCompiler.class, Compiler.class);
+    SpeedTracerLogger.init();
+    Event compileEvent = SpeedTracerLogger.start(CompilerEventType.COMPILE);
+
+    /*
+     * NOTE: main always exits with a call to System.exit to terminate any
+     * non-daemon threads that were started in Generators. Typically, this is to
+     * shutdown AWT related threads, since the contract for their termination is
+     * still implementation-dependent.
+     */
+    final LegacyCompilerOptions options = new GWTCompilerOptionsImpl();
+    boolean success = false;
+    if (new ArgProcessor(options).processArgs(args)) {
+      CompileTask task = new CompileTask() {
+        @Override
+        public boolean run(TreeLogger logger) throws UnableToCompleteException {
+          FutureTask<UpdateResult> updater = null;
+          if (!options.isUpdateCheckDisabled()) {
+            updater = CheckForUpdates.checkForUpdatesInBackgroundThread(logger,
+                CheckForUpdates.ONE_DAY);
+          }
+          boolean success = new GWTCompiler(options).run(logger);
+          if (success) {
+            CheckForUpdates.logUpdateAvailable(logger, updater);
+          }
+          return success;
+        }
+      };
+      if (CompileTaskRunner.runWithAppropriateLogger(options, task)) {
+        // Exit w/ success code.
+        success = true;
+      }
+    }
+
+    compileEvent.end();
+    // Exit w/ non-success code.
+    System.exit(success ? 0 : 1);
+  }
+
+  private final GWTCompilerOptionsImpl options;
+
+  public GWTCompiler(LegacyCompilerOptions options) {
+    this.options = new GWTCompilerOptionsImpl(options);
+  }
+
+  /**
+   * Compiles the set of modules specified in the options.
+   */
+  public boolean run(TreeLogger logger) throws UnableToCompleteException {
+    ModuleDef[] modules = new ModuleDef[options.getModuleNames().size()];
+    int i = 0;
+    for (String moduleName : options.getModuleNames()) {
+      modules[i++] = ModuleDefLoader.loadFromClassPath(logger, moduleName, true);
+    }
+    return run(logger, modules);
+  }
+
+  /**
+   * Compiles a specific set of modules.
+   */
+  public boolean run(TreeLogger logger, ModuleDef... modules)
+      throws UnableToCompleteException {
+    Event compileEvent = SpeedTracerLogger.start(CompilerEventType.COMPILE);
+    boolean tempWorkDir = false;
+    try {
+      if (options.getWorkDir() == null) {
+        options.setWorkDir(Utility.makeTemporaryDirectory(null, "gwtc"));
+        tempWorkDir = true;
+      }
+
+      for (ModuleDef module : modules) {
+        String moduleName = module.getName();
+
+        if (options.isValidateOnly()) {
+          if (!Precompile.validate(logger, options, module, options.getGenDir())) {
+            return false;
+          }
+        } else {
+          long compileStart = System.currentTimeMillis();
+          logger = logger.branch(TreeLogger.INFO, "Compiling module "
+              + moduleName);
+
+          // Optimize early since permutation compiles will run in process.
+          options.setOptimizePrecompile(true);
+          Precompilation precompilation = Precompile.precompile(logger,
+              options, module, options.getGenDir());
+
+          if (precompilation == null) {
+            return false;
+          }
+          Permutation[] allPerms = precompilation.getPermutations();
+          List<FileBackedObject<PermutationResult>> resultFiles = CompilePerms.makeResultFiles(
+              options.getCompilerWorkDir(moduleName), allPerms);
+          CompilePerms.compile(logger, precompilation, allPerms,
+              options.getLocalWorkers(), resultFiles);
+
+          ArtifactSet generatedArtifacts = precompilation.getGeneratedArtifacts();
+          JJSOptions precompileOptions = precompilation.getUnifiedAst().getOptions();
+
+          precompilation = null; // No longer needed, so save the memory
+
+          Link.legacyLink(logger.branch(TreeLogger.TRACE, "Linking into "
+              + options.getOutDir().getPath()), module, generatedArtifacts,
+              allPerms, resultFiles, options.getOutDir(), precompileOptions);
+
+          long compileDone = System.currentTimeMillis();
+          long delta = compileDone - compileStart;
+          if (logger.isLoggable(TreeLogger.INFO)) {
+            logger.log(TreeLogger.INFO, "Compilation succeeded -- "
+                + String.format("%.3f", delta / 1000d) + "s");
+          }
+        }
+      }
+    } catch (IOException e) {
+      logger.log(TreeLogger.ERROR, "Unable to create compiler work directory",
+          e);
+      return false;
+    } finally {
+      compileEvent.end();
+      if (tempWorkDir) {
+        Util.recursiveDelete(options.getWorkDir(), false);
+      }
+    }
+    return true;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java
new file mode 100644
index 0000000..77339ff
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/GWTShell.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2008 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
+import com.google.gwt.core.ext.linker.impl.StandardLinkerContext;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.shell.WorkDirs;
+import com.google.gwt.dev.shell.tomcat.EmbeddedTomcatServer;
+import com.google.gwt.dev.util.OutputFileSetOnDirectory;
+import com.google.gwt.dev.util.arg.ArgHandlerDisableUpdateCheck;
+import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
+import com.google.gwt.util.tools.ArgHandlerExtra;
+
+import java.io.File;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * The main executable class for the hosted mode shell.
+ */
+@Deprecated
+public class GWTShell extends DevModeBase {
+
+  /**
+   * Handles the list of startup urls that can be passed at the end of the
+   * command line.
+   */
+  protected static class ArgHandlerStartupURLsExtra extends ArgHandlerExtra {
+
+    private final OptionStartupURLs options;
+
+    public ArgHandlerStartupURLsExtra(OptionStartupURLs options) {
+      this.options = options;
+    }
+
+    @Override
+    public boolean addExtraArg(String arg) {
+      options.addStartupURL(arg);
+      return true;
+    }
+
+    @Override
+    public String getPurpose() {
+      return "Automatically launches the specified URL";
+    }
+
+    @Override
+    public String[] getTagArgs() {
+      return new String[] {"url"};
+    }
+  }
+
+  /**
+   * The GWTShell argument processor.
+   */
+  protected static class ArgProcessor extends DevModeBase.ArgProcessor {
+    public ArgProcessor(ShellOptionsImpl options, boolean forceServer,
+        boolean noURLs) {
+      super(options, forceServer);
+      if (!noURLs) {
+        registerHandler(new ArgHandlerStartupURLsExtra(options));
+      }
+      registerHandler(new ArgHandlerOutDir(options));
+      registerHandler(new ArgHandlerDisableUpdateCheck(options));
+    }
+
+    @Override
+    protected String getName() {
+      return GWTShell.class.getName();
+    }
+  }
+
+  /**
+   * Concrete class to implement all shell options.
+   */
+  protected static class ShellOptionsImpl extends HostedModeBaseOptionsImpl
+      implements WorkDirs, LegacyCompilerOptions {
+    private int localWorkers;
+    private File outDir;
+
+    public File getCompilerOutputDir(ModuleDef moduleDef) {
+      return new File(getOutDir(), moduleDef.getName());
+    }
+
+    public int getLocalWorkers() {
+      return localWorkers;
+    }
+
+    public File getOutDir() {
+      return outDir;
+    }
+
+    public File getShellPublicGenDir(ModuleDef moduleDef) {
+      File moduleWorkDir = new File(getWorkDir(), moduleDef.getName());
+      return new File(moduleWorkDir, "public");
+    }
+
+    @Override
+    public File getWorkDir() {
+      return new File(getOutDir(), ".gwt-tmp");
+    }
+
+    public void setLocalWorkers(int localWorkers) {
+      this.localWorkers = localWorkers;
+    }
+
+    public void setOutDir(File outDir) {
+      this.outDir = outDir;
+    }
+  }
+
+  public static String checkHost(String hostUnderConsideration,
+      Set<String> hosts) {
+    hostUnderConsideration = hostUnderConsideration.toLowerCase(Locale.ENGLISH);
+    for (String rule : hosts) {
+      // match on lowercased regex
+      if (hostUnderConsideration.matches(".*" + rule + ".*")) {
+        return rule;
+      }
+    }
+    return null;
+  }
+
+  public static String computeHostRegex(String url) {
+    // the entire URL up to the first slash not prefixed by a slash or colon.
+    String raw = url.split("(?<![:/])/")[0];
+    // escape the dots and put a begin line specifier on the result
+    return "^" + raw.replaceAll("[.]", "[.]");
+  }
+
+  public static String formatRules(Set<String> invalidHttpHosts) {
+    StringBuffer out = new StringBuffer();
+    for (String rule : invalidHttpHosts) {
+      out.append(rule);
+      out.append(" ");
+    }
+    return out.toString();
+  }
+
+  public static void main(String[] args) {
+    /*
+     * NOTE: main always exits with a call to System.exit to terminate any
+     * non-daemon threads that were started in Generators. Typically, this is to
+     * shutdown AWT related threads, since the contract for their termination is
+     * still implementation-dependent.
+     */
+    GWTShell gwtShell = new GWTShell();
+    ArgProcessor argProcessor = new ArgProcessor(gwtShell.options, false, false);
+    if (argProcessor.processArgs(args)) {
+      gwtShell.run();
+      // Exit w/ success code.
+      System.exit(0);
+    }
+    // Exit w/ non-success code.
+    System.exit(-1);
+  }
+
+  /**
+   * Hiding super field because it's actually the same object, just with a
+   * stronger type.
+   */
+  @SuppressWarnings("hiding")
+  protected final ShellOptionsImpl options = (ShellOptionsImpl) super.options;
+
+  protected File outDir;
+
+  @SuppressWarnings("unused")
+  public void restartServer(TreeLogger logger) throws UnableToCompleteException {
+    // Unimplemented.
+  }
+
+  @Override
+  protected HostedModeBaseOptions createOptions() {
+    return new ShellOptionsImpl();
+  }
+
+  @Override
+  protected void doShutDownServer() {
+    // Stop the HTTP server.
+    //
+    EmbeddedTomcatServer.stop();
+  }
+
+  @Override
+  protected boolean doStartup() {
+    File persistentCacheDir = new File(options.getWorkDir(), "gwt-unitCache");
+    return super.doStartup(persistentCacheDir);
+  }
+
+  @Override
+  protected int doStartUpServer() {
+    // TODO(jat): find a safe way to get an icon for Tomcat
+    TreeLogger logger = ui.getWebServerLogger("Tomcat", null);
+    // TODO(bruce): make tomcat work in terms of the modular launcher
+    String whyFailed = EmbeddedTomcatServer.start(isHeadless() ? getTopLogger()
+        : logger, getPort(), options, shouldAutoGenerateResources());
+
+    if (whyFailed != null) {
+      getTopLogger().log(TreeLogger.ERROR, "Starting Tomcat: " + whyFailed);
+      return -1;
+    }
+    return EmbeddedTomcatServer.getPort();
+  }
+
+  @Override
+  protected synchronized void produceOutput(TreeLogger logger,
+      StandardLinkerContext linkerStack, ArtifactSet artifacts,
+      ModuleDef module, boolean isRelink) throws UnableToCompleteException {
+    /*
+     * Legacy: in GWTShell we only copy generated artifacts into the public gen
+     * folder. Public files and "autogen" files have special handling (that
+     * needs to die).
+     */
+    if (isRelink) {
+      File outputDir = options.getShellPublicGenDir(module);
+      outputDir.mkdirs();
+      OutputFileSetOnDirectory outFileSet = new OutputFileSetOnDirectory(
+          outputDir, "");
+      linkerStack.produceOutput(logger, artifacts, Visibility.Public,
+          outFileSet);
+      outFileSet.close();
+    }
+  }
+
+  protected boolean shouldAutoGenerateResources() {
+    return true;
+  }
+
+  @Override
+  protected void warnAboutNoStartupUrls() {
+    getTopLogger().log(TreeLogger.WARN,
+        "No startup URLs were supplied -- add them to the end of the GWTShell"
+        + " command line");
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
index 378ab1a..8d972e9 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
@@ -466,9 +466,9 @@
   }
 
   /**
-   * For convenience in unit tests, servlets can be automatically loaded and
-   * mapped in the embedded web server. If a servlet is already mapped to the
-   * specified path, it is replaced.
+   * For convenience in hosted mode, servlets can be automatically loaded and
+   * delegated to via {@link com.google.gwt.dev.shell.GWTShellServlet}. If a
+   * servlet is already mapped to the specified path, it is replaced.
    * 
    * @param path the url path at which the servlet resides
    * @param servletClassName the name of the servlet to publish
diff --git a/dev/core/src/com/google/gwt/dev/etc/tomcat/conf/web.xml b/dev/core/src/com/google/gwt/dev/etc/tomcat/conf/web.xml
new file mode 100644
index 0000000..fee85f3
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/etc/tomcat/conf/web.xml
@@ -0,0 +1,566 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- A tweaked version of the default Tomcat web.xml to remove everything except the stuff we want to use -->
+<web-app version="2.4">
+
+    <session-config>
+        <session-timeout>30</session-timeout>
+    </session-config>
+
+    <mime-mapping>
+        <extension>abs</extension>
+        <mime-type>audio/x-mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ai</extension>
+        <mime-type>application/postscript</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>aif</extension>
+        <mime-type>audio/x-aiff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>aifc</extension>
+        <mime-type>audio/x-aiff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>aiff</extension>
+        <mime-type>audio/x-aiff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>aim</extension>
+        <mime-type>application/x-aim</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>art</extension>
+        <mime-type>image/x-jg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>asf</extension>
+        <mime-type>video/x-ms-asf</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>asx</extension>
+        <mime-type>video/x-ms-asf</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>au</extension>
+        <mime-type>audio/basic</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>avi</extension>
+        <mime-type>video/x-msvideo</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>avx</extension>
+        <mime-type>video/x-rad-screenplay</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>bcpio</extension>
+        <mime-type>application/x-bcpio</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>bin</extension>
+        <mime-type>application/octet-stream</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>bmp</extension>
+        <mime-type>image/bmp</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>body</extension>
+        <mime-type>text/html</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>cdf</extension>
+        <mime-type>application/x-cdf</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>cer</extension>
+        <mime-type>application/x-x509-ca-cert</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>class</extension>
+        <mime-type>application/java</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>cpio</extension>
+        <mime-type>application/x-cpio</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>csh</extension>
+        <mime-type>application/x-csh</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>css</extension>
+        <mime-type>text/css</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>dib</extension>
+        <mime-type>image/bmp</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>doc</extension>
+        <mime-type>application/msword</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>dtd</extension>
+        <mime-type>text/plain</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>dv</extension>
+        <mime-type>video/x-dv</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>dvi</extension>
+        <mime-type>application/x-dvi</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>eps</extension>
+        <mime-type>application/postscript</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>etx</extension>
+        <mime-type>text/x-setext</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>exe</extension>
+        <mime-type>application/octet-stream</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>gif</extension>
+        <mime-type>image/gif</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>gtar</extension>
+        <mime-type>application/x-gtar</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>gz</extension>
+        <mime-type>application/x-gzip</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>hdf</extension>
+        <mime-type>application/x-hdf</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>hqx</extension>
+        <mime-type>application/mac-binhex40</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>htc</extension>
+        <mime-type>text/x-component</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>htm</extension>
+        <mime-type>text/html</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>html</extension>
+        <mime-type>text/html</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>hqx</extension>
+        <mime-type>application/mac-binhex40</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ief</extension>
+        <mime-type>image/ief</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jad</extension>
+        <mime-type>text/vnd.sun.j2me.app-descriptor</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jar</extension>
+        <mime-type>application/java-archive</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>java</extension>
+        <mime-type>text/plain</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jnlp</extension>
+        <mime-type>application/x-java-jnlp-file</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jpe</extension>
+        <mime-type>image/jpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jpeg</extension>
+        <mime-type>image/jpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jpg</extension>
+        <mime-type>image/jpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>js</extension>
+        <mime-type>text/javascript</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jsf</extension>
+        <mime-type>text/plain</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>jspf</extension>
+        <mime-type>text/plain</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>kar</extension>
+        <mime-type>audio/x-midi</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>latex</extension>
+        <mime-type>application/x-latex</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>m3u</extension>
+        <mime-type>audio/x-mpegurl</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mac</extension>
+        <mime-type>image/x-macpaint</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>man</extension>
+        <mime-type>application/x-troff-man</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>me</extension>
+        <mime-type>application/x-troff-me</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mid</extension>
+        <mime-type>audio/x-midi</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>midi</extension>
+        <mime-type>audio/x-midi</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mif</extension>
+        <mime-type>application/x-mif</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mov</extension>
+        <mime-type>video/quicktime</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>movie</extension>
+        <mime-type>video/x-sgi-movie</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mp1</extension>
+        <mime-type>audio/x-mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mp2</extension>
+        <mime-type>audio/x-mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mp3</extension>
+        <mime-type>audio/x-mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mpa</extension>
+        <mime-type>audio/x-mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mpe</extension>
+        <mime-type>video/mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mpeg</extension>
+        <mime-type>video/mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mpega</extension>
+        <mime-type>audio/x-mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mpg</extension>
+        <mime-type>video/mpeg</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>mpv2</extension>
+        <mime-type>video/mpeg2</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ms</extension>
+        <mime-type>application/x-wais-source</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>nc</extension>
+        <mime-type>application/x-netcdf</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>oda</extension>
+        <mime-type>application/oda</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pbm</extension>
+        <mime-type>image/x-portable-bitmap</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pct</extension>
+        <mime-type>image/pict</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pdf</extension>
+        <mime-type>application/pdf</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pgm</extension>
+        <mime-type>image/x-portable-graymap</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pic</extension>
+        <mime-type>image/pict</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pict</extension>
+        <mime-type>image/pict</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pls</extension>
+        <mime-type>audio/x-scpls</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>png</extension>
+        <mime-type>image/png</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pnm</extension>
+        <mime-type>image/x-portable-anymap</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>pnt</extension>
+        <mime-type>image/x-macpaint</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ppm</extension>
+        <mime-type>image/x-portable-pixmap</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ppt</extension>
+        <mime-type>application/powerpoint</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ps</extension>
+        <mime-type>application/postscript</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>psd</extension>
+        <mime-type>image/x-photoshop</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>qt</extension>
+        <mime-type>video/quicktime</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>qti</extension>
+        <mime-type>image/x-quicktime</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>qtif</extension>
+        <mime-type>image/x-quicktime</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ras</extension>
+        <mime-type>image/x-cmu-raster</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>rgb</extension>
+        <mime-type>image/x-rgb</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>rm</extension>
+        <mime-type>application/vnd.rn-realmedia</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>roff</extension>
+        <mime-type>application/x-troff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>rtf</extension>
+        <mime-type>application/rtf</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>rtx</extension>
+        <mime-type>text/richtext</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>sh</extension>
+        <mime-type>application/x-sh</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>shar</extension>
+        <mime-type>application/x-shar</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>smf</extension>
+        <mime-type>audio/x-midi</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>sit</extension>
+        <mime-type>application/x-stuffit</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>snd</extension>
+        <mime-type>audio/basic</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>src</extension>
+        <mime-type>application/x-wais-source</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>sv4cpio</extension>
+        <mime-type>application/x-sv4cpio</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>sv4crc</extension>
+        <mime-type>application/x-sv4crc</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>swf</extension>
+        <mime-type>application/x-shockwave-flash</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>t</extension>
+        <mime-type>application/x-troff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>tar</extension>
+        <mime-type>application/x-tar</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>tcl</extension>
+        <mime-type>application/x-tcl</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>tex</extension>
+        <mime-type>application/x-tex</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>texi</extension>
+        <mime-type>application/x-texinfo</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>texinfo</extension>
+        <mime-type>application/x-texinfo</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>tif</extension>
+        <mime-type>image/tiff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>tiff</extension>
+        <mime-type>image/tiff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>tr</extension>
+        <mime-type>application/x-troff</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>tsv</extension>
+        <mime-type>text/tab-separated-values</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>txt</extension>
+        <mime-type>text/plain</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ulw</extension>
+        <mime-type>audio/basic</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>ustar</extension>
+        <mime-type>application/x-ustar</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>xbm</extension>
+        <mime-type>image/x-xbitmap</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>xht</extension>
+        <mime-type>application/xhtml+xml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>xhtml</extension>
+        <mime-type>application/xhtml+xml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>xml</extension>
+        <mime-type>text/xml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>xpm</extension>
+        <mime-type>image/x-xpixmap</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>xsl</extension>
+        <mime-type>text/xml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>xwd</extension>
+        <mime-type>image/x-xwindowdump</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>wav</extension>
+        <mime-type>audio/x-wav</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>svg</extension>
+        <mime-type>image/svg+xml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>svgz</extension>
+        <mime-type>image/svg+xml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>vsd</extension>
+        <mime-type>application/x-visio</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <!-- Wireless Bitmap -->
+        <extension>wbmp</extension>
+        <mime-type>image/vnd.wap.wbmp</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <!-- WML Source -->
+        <extension>wml</extension>
+        <mime-type>text/vnd.wap.wml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <!-- Compiled WML -->
+        <extension>wmlc</extension>
+        <mime-type>application/vnd.wap.wmlc</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <!-- WML Script Source -->
+        <extension>wmls</extension>
+        <mime-type>text/vnd.wap.wmlscript</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <!-- Compiled WML Script -->
+        <extension>wmlscriptc</extension>
+        <mime-type>application/vnd.wap.wmlscriptc</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>wrl</extension>
+        <mime-type>x-world/x-vrml</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>Z</extension>
+        <mime-type>application/x-compress</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>z</extension>
+        <mime-type>application/x-compress</mime-type>
+    </mime-mapping>
+    <mime-mapping>
+        <extension>zip</extension>
+        <mime-type>application/zip</mime-type>
+    </mime-mapping>
+</web-app>
diff --git a/dev/core/src/com/google/gwt/dev/etc/tomcat/webapps/ROOT/WEB-INF/web.xml b/dev/core/src/com/google/gwt/dev/etc/tomcat/webapps/ROOT/WEB-INF/web.xml
new file mode 100644
index 0000000..e600b2f
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/etc/tomcat/webapps/ROOT/WEB-INF/web.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app>
+
+	<servlet>
+		<servlet-name>shell</servlet-name>
+		<servlet-class>com.google.gwt.dev.shell.GWTShellServlet</servlet-class>
+	</servlet>
+	
+	<servlet-mapping>
+		<servlet-name>shell</servlet-name>
+		<url-pattern>/*</url-pattern>
+	</servlet-mapping>
+
+</web-app>
diff --git a/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java b/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java
new file mode 100644
index 0000000..9e7ead7
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/GWTShellServlet.java
@@ -0,0 +1,991 @@
+/*
+ * Copyright 2008 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.core.ext.linker.impl.HostedModeLinker;
+import com.google.gwt.core.ext.linker.impl.StandardLinkerContext;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.cfg.ModuleDefLoader;
+import com.google.gwt.dev.jjs.JJSOptionsImpl;
+import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.dev.shell.log.ServletContextTreeLogger;
+import com.google.gwt.dev.util.HttpHeaders;
+import com.google.gwt.dev.util.Util;
+import com.google.gwt.thirdparty.guava.common.collect.MapMaker;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Built-in servlet for convenient access to the public path of a specified
+ * module.
+ */
+public class GWTShellServlet extends HttpServlet {
+
+  private static class RequestParts {
+    public final String moduleName;
+
+    public final String partialPath;
+
+    public RequestParts(HttpServletRequest request)
+        throws UnableToCompleteException {
+      String pathInfo = request.getPathInfo();
+      if (pathInfo != null) {
+        int slash = pathInfo.indexOf('/', 1);
+        if (slash != -1) {
+          moduleName = pathInfo.substring(1, slash);
+          partialPath = pathInfo.substring(slash + 1);
+          return;
+        } else {
+          moduleName = pathInfo.substring(1);
+          partialPath = null;
+          return;
+        }
+      }
+      throw new UnableToCompleteException();
+    }
+  }
+
+  /**
+   * This the default cache time in seconds for files that aren't either
+   * *.cache.*, *.nocache.*.
+   */
+  private static final int DEFAULT_CACHE_SECONDS = 5;
+
+  private static final String XHTML_MIME_TYPE = "application/xhtml+xml";
+
+  /**
+   * Must keep only weak references to ModuleDefs else we permanently pin them.
+   */
+  private final Map<String, ModuleDef> loadedModulesByName = new MapMaker().weakValues().makeMap();
+
+  /**
+   * The lifetime of the module pins the lifetime of the associated servlet;
+   * this is because the loaded servlet has a weak backRef to its live module
+   * through its context. When the module dies, the servlet needs to die also.
+   */
+  private final Map<ModuleDef, Map<String, HttpServlet>> loadedServletsByModuleAndClassName =
+      new MapMaker().weakKeys().makeMap();
+
+  private final Map<String, String> mimeTypes = new HashMap<String, String>();
+
+  /**
+   * Only for backwards compatibility. Shouldn't we remove this now?
+   */
+  private final Map<String, ModuleDef> modulesByServletPath = new MapMaker().weakValues().makeMap();
+
+  private int nextRequestId;
+
+  private final Object requestIdLock = new Object();
+
+  private TreeLogger topLogger;
+
+  private WorkDirs workDirs;
+
+  public GWTShellServlet() {
+    initMimeTypes();
+  }
+
+  @Override
+  protected void doGet(HttpServletRequest request, HttpServletResponse response)
+      throws ServletException, IOException {
+    processFileRequest(request, response);
+  }
+
+  @Override
+  protected void doPost(HttpServletRequest request, HttpServletResponse response)
+      throws ServletException, IOException {
+    processFileRequest(request, response);
+  }
+
+  protected void processFileRequest(HttpServletRequest request,
+      HttpServletResponse response) throws IOException {
+
+    String pathInfo = request.getPathInfo();
+    if (pathInfo.length() == 0 || pathInfo.equals("/")) {
+      response.setContentType("text/html");
+      PrintWriter writer = response.getWriter();
+      writer.println("<html><body><basefont face='arial'>");
+      writer.println("To launch an application, specify a URL of the form <code>/<i>module</i>/<i>file.html</i></code>");
+      writer.println("</body></html>");
+      return;
+    }
+
+    TreeLogger logger = getLogger();
+
+    // Parse the request assuming it is module/resource.
+    //
+    RequestParts parts;
+    try {
+      parts = new RequestParts(request);
+    } catch (UnableToCompleteException e) {
+      sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND,
+          "Don't know what to do with this URL: '" + pathInfo + "'");
+      return;
+    }
+
+    String partialPath = parts.partialPath;
+    String moduleName = parts.moduleName;
+
+    // If the module is renamed, substitute the renamed module name
+    ModuleDef moduleDef = loadedModulesByName.get(moduleName);
+    if (moduleDef != null) {
+      moduleName = moduleDef.getName();
+    }
+
+    if (partialPath == null) {
+      // Redir back to the same URL but ending with a slash.
+      //
+      response.sendRedirect(moduleName + "/");
+      return;
+    } else if (partialPath.length() > 0) {
+      // Both the module name and a resource.
+      //
+      doGetPublicFile(request, response, logger, partialPath, moduleName);
+      return;
+    } else {
+      // Was just the module name, ending with a slash.
+      //
+      doGetModule(request, response, logger, parts);
+      return;
+    }
+  }
+
+  @Override
+  protected void service(HttpServletRequest request,
+      HttpServletResponse response) throws ServletException, IOException {
+
+    TreeLogger logger = getLogger();
+    int id = allocateRequestId();
+    if (logger.isLoggable(TreeLogger.TRACE)) {
+      StringBuffer url = request.getRequestURL();
+
+      // Branch the logger in case we decide to log more below.
+      logger = logger.branch(TreeLogger.TRACE, "Request " + id + ": " + url,
+          null);
+    }
+
+    String servletClassName = null;
+    ModuleDef moduleDef = null;
+
+    try {
+      // Attempt to split the URL into module/path, which we'll use to see
+      // if we can map the request to a module's servlet.
+      RequestParts parts = new RequestParts(request);
+
+      if ("favicon.ico".equalsIgnoreCase(parts.moduleName)) {
+        sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND,
+            "Icon not available");
+        return;
+      }
+
+      // See if the request references a module we know.
+      moduleDef = getModuleDef(logger, parts.moduleName);
+      if (moduleDef != null) {
+        // Okay, we know this module. Do we know this servlet path?
+        // It is right to prepend the slash because (1) ModuleDefSchema requires
+        // every servlet path to begin with a slash and (2) RequestParts always
+        // rips off the leading slash.
+        String servletPath = "/" + parts.partialPath;
+        servletClassName = moduleDef.findServletForPath(servletPath);
+
+        // Fall-through below, where we check servletClassName.
+      } else {
+        // Fall-through below, where we check servletClassName.
+      }
+    } catch (UnableToCompleteException e) {
+      // Do nothing, since it was speculative anyway.
+    }
+
+    // BEGIN BACKWARD COMPATIBILITY
+    if (servletClassName == null) {
+      // Try to map a bare path that isn't preceded by the module name.
+      // This is no longer the recommended practice, so we warn.
+      String path = request.getPathInfo();
+      moduleDef = modulesByServletPath.get(path);
+      if (moduleDef != null) {
+        // See if there is a servlet we can delegate to for the given url.
+        servletClassName = moduleDef.findServletForPath(path);
+
+        if (servletClassName != null) {
+          TreeLogger branch = logger.branch(TreeLogger.WARN,
+              "Use of deprecated hosted mode servlet path mapping", null);
+          branch.log(
+              TreeLogger.WARN,
+              "The client code is invoking the servlet with a URL that is not module-relative: "
+                  + path, null);
+          branch.log(
+              TreeLogger.WARN,
+              "Prepend GWT.getModuleBaseURL() to the URL in client code to create a module-relative URL: /"
+                  + moduleDef.getName() + path, null);
+          branch.log(
+              TreeLogger.WARN,
+              "Using module-relative URLs ensures correct URL-independent behavior in external servlet containers",
+              null);
+        }
+
+        // Fall-through below, where we check servletClassName.
+      } else {
+        // Fall-through below, where we check servletClassName.
+      }
+    }
+    // END BACKWARD COMPATIBILITY
+
+    // Load/get the servlet if we found one.
+    if (servletClassName != null) {
+      HttpServlet delegatee = tryGetOrLoadServlet(logger, moduleDef,
+          servletClassName);
+      if (delegatee == null) {
+        logger.log(TreeLogger.ERROR, "Unable to dispatch request", null);
+        sendErrorResponse(response,
+            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+            "Unable to find/load mapped servlet class '" + servletClassName
+                + "'");
+        return;
+      }
+
+      // Delegate everything to the downstream servlet and we're done.
+      delegatee.service(request, response);
+    } else {
+      // Use normal default processing on this request, since we couldn't
+      // recognize it as anything special.
+      super.service(request, response);
+    }
+  }
+
+  private int allocateRequestId() {
+    synchronized (requestIdLock) {
+      return nextRequestId++;
+    }
+  }
+
+  /**
+   * Handle auto-generated resources.
+   * 
+   * @return <code>true</code> if a resource was generated
+   */
+  private boolean autoGenerateResources(HttpServletRequest request,
+      HttpServletResponse response, TreeLogger logger, String partialPath,
+      String moduleName) throws IOException {
+
+    if (partialPath.equals(moduleName + ".nocache.js")) {
+      if (request.getParameter("compiled") == null) {
+        // Generate the .js file.
+        try {
+          String js = genSelectionScript(logger, moduleName);
+          setResponseCacheHeaders(response, 0); // do not cache selection script
+          response.setStatus(HttpServletResponse.SC_OK);
+          response.setContentType("text/javascript");
+          response.getWriter().println(js);
+          return true;
+        } catch (UnableToCompleteException e) {
+          // The error will have already been logged. Continue, since this could
+          // actually be a request for a static file that happens to have an
+          // unfortunately confusing name.
+        }
+      }
+    } else if (partialPath.equals("hosted.html")) {
+      String html = HostedModeLinker.getHostedHtml();
+      setResponseCacheHeaders(response, DEFAULT_CACHE_SECONDS);
+      response.setStatus(HttpServletResponse.SC_OK);
+      response.setContentType("text/html");
+      response.getWriter().println(html);
+      return true;
+    }
+
+    return false;
+  }
+
+  private void doGetModule(HttpServletRequest request,
+      HttpServletResponse response, TreeLogger logger, RequestParts parts)
+      throws IOException {
+
+    // Generate a generic empty host page.
+    //
+    String msg = "The development shell servlet received a request to generate a host page for module '"
+        + parts.moduleName + "' ";
+
+    logger = logger.branch(TreeLogger.TRACE, msg, null);
+
+    try {
+      // Try to load the module just to make sure it'll work.
+      getModuleDef(logger, parts.moduleName);
+    } catch (UnableToCompleteException e) {
+      sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND,
+          "Unable to find/load module '" + Util.escapeXml(parts.moduleName)
+              + "' (see server log for details)");
+      return;
+    }
+
+    response.setContentType("text/html");
+    PrintWriter writer = response.getWriter();
+    writer.println("<html><head>");
+    writer.print("<script language='javascript' src='");
+    writer.print(parts.moduleName);
+    writer.println(".nocache.js'></script>");
+
+    // Create a property for each query param.
+    Map<String, String[]> params = getParameterMap(request);
+    for (Map.Entry<String, String[]> entry : params.entrySet()) {
+      String[] values = entry.getValue();
+      if (values.length > 0) {
+        writer.print("<meta name='gwt:property' content='");
+        writer.print(entry.getKey());
+        writer.print("=");
+        writer.print(values[values.length - 1]);
+        writer.println("'>");
+      }
+    }
+
+    writer.println("</head><body>");
+    writer.println("<iframe src=\"javascript:''\" id='__gwt_historyFrame' "
+        + "style='position:absolute;width:0;height:0;border:0'></iframe>");
+    writer.println("<noscript>");
+    writer.println("  <div style=\"width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif\">");
+    writer.println("    Your web browser must have JavaScript enabled");
+    writer.println("    in order for this application to display correctly.");
+    writer.println("  </div>");
+    writer.println("</noscript>");
+    writer.println("</body></html>");
+
+    // Done.
+  }
+
+  /**
+   * Fetch a file and return it as the HTTP response, setting the cache-related
+   * headers according to the name of the file (see
+   * {@link #getCacheTime(String)}). This function honors If-Modified-Since to
+   * minimize the impact of limiting caching of files for development.
+   * 
+   * @param request the HTTP request
+   * @param response the HTTP response
+   * @param logger a TreeLogger to use for debug output
+   * @param partialPath the path within the module
+   * @param moduleName the name of the module
+   * @throws IOException
+   */
+  @SuppressWarnings("deprecation")
+  private void doGetPublicFile(HttpServletRequest request,
+      HttpServletResponse response, TreeLogger logger, String partialPath,
+      String moduleName) throws IOException {
+
+    // Create a logger branch for this request.
+    logger = logger.branch(TreeLogger.TRACE,
+        "The development shell servlet received a request for '"
+        + partialPath + "' in module '" + moduleName + ".gwt.xml' ", null);
+
+    // Handle auto-generation of resources.
+    if (shouldAutoGenerateResources()) {
+      if (autoGenerateResources(request, response, logger, partialPath,
+          moduleName)) {
+        return;
+      }
+    }
+
+    URL foundResource = null;
+    try {
+      // Look for the requested file on the public path.
+      //
+      ModuleDef moduleDef = getModuleDef(logger, moduleName);
+      if (shouldAutoGenerateResources()) {
+        Resource publicResource = moduleDef.findPublicFile(partialPath);
+        if (publicResource != null) {
+          foundResource = publicResource.getURL();
+        }
+
+        if (foundResource == null) {
+          // Look for public generated files
+          File shellDir = getShellWorkDirs().getShellPublicGenDir(moduleDef);
+          File requestedFile = new File(shellDir, partialPath);
+          if (requestedFile.exists()) {
+            try {
+              foundResource = requestedFile.toURI().toURL();
+            } catch (MalformedURLException e) {
+              // ignore since it was speculative anyway
+            }
+          }
+        }
+      }
+
+      /*
+       * If the user is coming from compiled web-mode, check the linker output
+       * directory for the real bootstrap file.
+       */
+      if (foundResource == null) {
+        File moduleDir = getShellWorkDirs().getCompilerOutputDir(moduleDef);
+        File requestedFile = new File(moduleDir, partialPath);
+        if (requestedFile.exists()) {
+          try {
+            foundResource = requestedFile.toURI().toURL();
+          } catch (MalformedURLException e) {
+            // ignore since it was speculative anyway
+          }
+        }
+      }
+
+      if (foundResource == null) {
+        String msg;
+        if ("gwt.js".equals(partialPath)) {
+          msg = "Loading the old 'gwt.js' bootstrap script is no longer supported; please load '"
+              + moduleName + ".nocache.js' directly";
+        } else {
+          msg = "Resource not found: " + partialPath + "; "
+              + "(could a file be missing from the public path or a <servlet> "
+              + "tag misconfigured in module " + moduleName + ".gwt.xml ?)";
+        }
+        logger.log(TreeLogger.WARN, msg, null);
+        throw new UnableToCompleteException();
+      }
+    } catch (UnableToCompleteException e) {
+      sendErrorResponse(response, HttpServletResponse.SC_NOT_FOUND,
+          "Cannot find resource '" + partialPath
+              + "' in the public path of module '" + moduleName + "'");
+      return;
+    }
+
+    // Get the MIME type.
+    String path = foundResource.toExternalForm();
+    String mimeType = null;
+    try {
+      mimeType = getServletContext().getMimeType(path);
+    } catch (UnsupportedOperationException e) {
+      // Certain minimalist servlet containers throw this.
+      // Fall through to guess the type.
+    }
+
+    if (mimeType == null) {
+      mimeType = guessMimeType(path);
+      if (logger.isLoggable(TreeLogger.TRACE)) {
+        logger.log(TreeLogger.TRACE, "Guessed MIME type '" + mimeType + "'", null);
+      }
+    }
+
+    maybeIssueXhtmlWarning(logger, mimeType, partialPath);
+
+    long cacheSeconds = getCacheTime(path);
+
+    InputStream is = null;
+    try {
+      // Check for up-to-datedness.
+      URLConnection conn = foundResource.openConnection();
+      long lastModified = conn.getLastModified();
+      if (isNotModified(request, lastModified)) {
+        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+        setResponseCacheHeaders(response, cacheSeconds);
+        return;
+      }
+
+      // Set up headers to really send it.
+      response.setStatus(HttpServletResponse.SC_OK);
+      long now = new Date().getTime();
+      response.setHeader(HttpHeaders.DATE,
+          HttpHeaders.toInternetDateFormat(now));
+      response.setContentType(mimeType);
+      String lastModifiedStr = HttpHeaders.toInternetDateFormat(lastModified);
+      response.setHeader(HttpHeaders.LAST_MODIFIED, lastModifiedStr);
+
+      // Expiration header. Either immediately stale (requiring an
+      // "If-Modified-Since") or infinitely cacheable (not requiring even a
+      // freshness check).
+      setResponseCacheHeaders(response, cacheSeconds);
+
+      // Content length.
+      int contentLength = conn.getContentLength();
+      if (contentLength >= 0) {
+        response.setHeader(HttpHeaders.CONTENT_LENGTH,
+            Integer.toString(contentLength));
+      }
+
+      // Send the bytes.
+      is = conn.getInputStream();
+      streamOut(is, response.getOutputStream(), 1024 * 8);
+    } finally {
+      Utility.close(is);
+    }
+  }
+
+  /**
+   * Generates a module.js file on the fly. Note that the nocache file that is
+   * generated that can only be used for hosted mode. It cannot produce a web
+   * mode version, since this servlet doesn't know strong names, since by
+   * definition of "hosted mode" JavaScript hasn't been compiled at this point.
+   */
+  private String genSelectionScript(TreeLogger logger, String moduleName)
+      throws UnableToCompleteException {
+    if (logger.isLoggable(TreeLogger.TRACE)) {
+      logger.log(TreeLogger.TRACE,
+          "Generating a script selection script for module " + moduleName);
+    }
+    ModuleDef module = getModuleDef(logger, moduleName);
+    StandardLinkerContext context = new StandardLinkerContext(logger, module,
+        new JJSOptionsImpl());
+    ArtifactSet artifacts = context.getArtifactsForPublicResources(logger,
+        module);
+    HostedModeLinker linker = new HostedModeLinker();
+    return linker.generateSelectionScript(logger, context, artifacts);
+  }
+
+  /**
+   * Get the length of time a given file should be cacheable. If the path
+   * contains *.nocache.*, it is never cacheable; if it contains *.cache.*, it
+   * is infinitely cacheable; anything else gets a default time.
+   * 
+   * @return cache time in seconds, or 0 if the file is not cacheable at all
+   */
+  private long getCacheTime(String path) {
+    int lastDot = path.lastIndexOf('.');
+    if (lastDot >= 0) {
+      String prefix = path.substring(0, lastDot);
+      if (prefix.endsWith(".cache")) {
+        // RFC2616 says to never give a cache time of more than a year
+        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21
+        return HttpHeaders.SEC_YR;
+      } else if (prefix.endsWith(".nocache")) {
+        return 0;
+      }
+    }
+    return DEFAULT_CACHE_SECONDS;
+  }
+
+  private synchronized TreeLogger getLogger() {
+    if (topLogger == null) {
+      ServletContext servletContext = getServletContext();
+      final String attr = "com.google.gwt.dev.shell.logger";
+      topLogger = (TreeLogger) servletContext.getAttribute(attr);
+      if (topLogger == null) {
+        // No shell available, so wrap the regular servlet context logger.
+        //
+        topLogger = new ServletContextTreeLogger(servletContext);
+      }
+    }
+    return topLogger;
+  }
+
+  /**
+   * We don't actually log this on purpose since the client does anyway.
+   */
+  private ModuleDef getModuleDef(TreeLogger logger, String moduleName)
+      throws UnableToCompleteException {
+    synchronized (loadedModulesByName) {
+      ModuleDef moduleDef = loadedModulesByName.get(moduleName);
+      if (moduleDef == null) {
+        moduleDef = ModuleDefLoader.loadFromClassPath(logger, moduleName, false);
+        loadedModulesByName.put(moduleName, moduleDef);
+        loadedModulesByName.put(moduleDef.getName(), moduleDef);
+
+        // BEGIN BACKWARD COMPATIBILITY
+        // The following map of servlet path to module is included only
+        // for backward-compatibility. We are going to remove this functionality
+        // when we go out of beta. The new behavior is that the client should
+        // specify the module name as part of the URL and construct it using
+        // getModuleBaseURL().
+        String[] servletPaths = moduleDef.getServletPaths();
+        for (int i = 0; i < servletPaths.length; i++) {
+          modulesByServletPath.put(servletPaths[i], moduleDef);
+        }
+        // END BACKWARD COMPATIBILITY
+      }
+      return moduleDef;
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private Map<String, String[]> getParameterMap(HttpServletRequest request) {
+    return request.getParameterMap();
+  }
+
+  private synchronized WorkDirs getShellWorkDirs() {
+    if (workDirs == null) {
+      ServletContext servletContext = getServletContext();
+      final String attr = "com.google.gwt.dev.shell.workdirs";
+      workDirs = (WorkDirs) servletContext.getAttribute(attr);
+      assert (workDirs != null);
+    }
+    return workDirs;
+  }
+
+  private String guessMimeType(String fullPath) {
+    int dot = fullPath.lastIndexOf('.');
+    if (dot != -1) {
+      String ext = fullPath.substring(dot + 1);
+      String mimeType = mimeTypes.get(ext);
+      if (mimeType != null) {
+        return mimeType;
+      }
+
+      // Otherwise, fall through.
+      //
+    }
+
+    // Last resort.
+    //
+    return "application/octet-stream";
+  }
+
+  private void initMimeTypes() {
+    mimeTypes.put("abs", "audio/x-mpeg");
+    mimeTypes.put("ai", "application/postscript");
+    mimeTypes.put("aif", "audio/x-aiff");
+    mimeTypes.put("aifc", "audio/x-aiff");
+    mimeTypes.put("aiff", "audio/x-aiff");
+    mimeTypes.put("aim", "application/x-aim");
+    mimeTypes.put("art", "image/x-jg");
+    mimeTypes.put("asf", "video/x-ms-asf");
+    mimeTypes.put("asx", "video/x-ms-asf");
+    mimeTypes.put("au", "audio/basic");
+    mimeTypes.put("avi", "video/x-msvideo");
+    mimeTypes.put("avx", "video/x-rad-screenplay");
+    mimeTypes.put("bcpio", "application/x-bcpio");
+    mimeTypes.put("bin", "application/octet-stream");
+    mimeTypes.put("bmp", "image/bmp");
+    mimeTypes.put("body", "text/html");
+    mimeTypes.put("cdf", "application/x-cdf");
+    mimeTypes.put("cer", "application/x-x509-ca-cert");
+    mimeTypes.put("class", "application/java");
+    mimeTypes.put("cpio", "application/x-cpio");
+    mimeTypes.put("csh", "application/x-csh");
+    mimeTypes.put("css", "text/css");
+    mimeTypes.put("dib", "image/bmp");
+    mimeTypes.put("doc", "application/msword");
+    mimeTypes.put("dtd", "text/plain");
+    mimeTypes.put("dv", "video/x-dv");
+    mimeTypes.put("dvi", "application/x-dvi");
+    mimeTypes.put("eps", "application/postscript");
+    mimeTypes.put("etx", "text/x-setext");
+    mimeTypes.put("exe", "application/octet-stream");
+    mimeTypes.put("gif", "image/gif");
+    mimeTypes.put("gtar", "application/x-gtar");
+    mimeTypes.put("gz", "application/x-gzip");
+    mimeTypes.put("hdf", "application/x-hdf");
+    mimeTypes.put("hqx", "application/mac-binhex40");
+    mimeTypes.put("htc", "text/x-component");
+    mimeTypes.put("htm", "text/html");
+    mimeTypes.put("html", "text/html");
+    mimeTypes.put("hqx", "application/mac-binhex40");
+    mimeTypes.put("ief", "image/ief");
+    mimeTypes.put("jad", "text/vnd.sun.j2me.app-descriptor");
+    mimeTypes.put("jar", "application/java-archive");
+    mimeTypes.put("java", "text/plain");
+    mimeTypes.put("jnlp", "application/x-java-jnlp-file");
+    mimeTypes.put("jpe", "image/jpeg");
+    mimeTypes.put("jpeg", "image/jpeg");
+    mimeTypes.put("jpg", "image/jpeg");
+    mimeTypes.put("js", "text/javascript");
+    mimeTypes.put("jsf", "text/plain");
+    mimeTypes.put("jspf", "text/plain");
+    mimeTypes.put("kar", "audio/x-midi");
+    mimeTypes.put("latex", "application/x-latex");
+    mimeTypes.put("m3u", "audio/x-mpegurl");
+    mimeTypes.put("mac", "image/x-macpaint");
+    mimeTypes.put("man", "application/x-troff-man");
+    mimeTypes.put("me", "application/x-troff-me");
+    mimeTypes.put("mid", "audio/x-midi");
+    mimeTypes.put("midi", "audio/x-midi");
+    mimeTypes.put("mif", "application/x-mif");
+    mimeTypes.put("mov", "video/quicktime");
+    mimeTypes.put("movie", "video/x-sgi-movie");
+    mimeTypes.put("mp1", "audio/x-mpeg");
+    mimeTypes.put("mp2", "audio/x-mpeg");
+    mimeTypes.put("mp3", "audio/x-mpeg");
+    mimeTypes.put("mpa", "audio/x-mpeg");
+    mimeTypes.put("mpe", "video/mpeg");
+    mimeTypes.put("mpeg", "video/mpeg");
+    mimeTypes.put("mpega", "audio/x-mpeg");
+    mimeTypes.put("mpg", "video/mpeg");
+    mimeTypes.put("mpv2", "video/mpeg2");
+    mimeTypes.put("ms", "application/x-wais-source");
+    mimeTypes.put("nc", "application/x-netcdf");
+    mimeTypes.put("oda", "application/oda");
+    mimeTypes.put("pbm", "image/x-portable-bitmap");
+    mimeTypes.put("pct", "image/pict");
+    mimeTypes.put("pdf", "application/pdf");
+    mimeTypes.put("pgm", "image/x-portable-graymap");
+    mimeTypes.put("pic", "image/pict");
+    mimeTypes.put("pict", "image/pict");
+    mimeTypes.put("pls", "audio/x-scpls");
+    mimeTypes.put("png", "image/png");
+    mimeTypes.put("pnm", "image/x-portable-anymap");
+    mimeTypes.put("pnt", "image/x-macpaint");
+    mimeTypes.put("ppm", "image/x-portable-pixmap");
+    mimeTypes.put("ppt", "application/powerpoint");
+    mimeTypes.put("ps", "application/postscript");
+    mimeTypes.put("psd", "image/x-photoshop");
+    mimeTypes.put("qt", "video/quicktime");
+    mimeTypes.put("qti", "image/x-quicktime");
+    mimeTypes.put("qtif", "image/x-quicktime");
+    mimeTypes.put("ras", "image/x-cmu-raster");
+    mimeTypes.put("rgb", "image/x-rgb");
+    mimeTypes.put("rm", "application/vnd.rn-realmedia");
+    mimeTypes.put("roff", "application/x-troff");
+    mimeTypes.put("rtf", "application/rtf");
+    mimeTypes.put("rtx", "text/richtext");
+    mimeTypes.put("sh", "application/x-sh");
+    mimeTypes.put("shar", "application/x-shar");
+    mimeTypes.put("smf", "audio/x-midi");
+    mimeTypes.put("sit", "application/x-stuffit");
+    mimeTypes.put("snd", "audio/basic");
+    mimeTypes.put("src", "application/x-wais-source");
+    mimeTypes.put("sv4cpio", "application/x-sv4cpio");
+    mimeTypes.put("sv4crc", "application/x-sv4crc");
+    mimeTypes.put("swf", "application/x-shockwave-flash");
+    mimeTypes.put("t", "application/x-troff");
+    mimeTypes.put("tar", "application/x-tar");
+    mimeTypes.put("tcl", "application/x-tcl");
+    mimeTypes.put("tex", "application/x-tex");
+    mimeTypes.put("texi", "application/x-texinfo");
+    mimeTypes.put("texinfo", "application/x-texinfo");
+    mimeTypes.put("tif", "image/tiff");
+    mimeTypes.put("tiff", "image/tiff");
+    mimeTypes.put("tr", "application/x-troff");
+    mimeTypes.put("tsv", "text/tab-separated-values");
+    mimeTypes.put("txt", "text/plain");
+    mimeTypes.put("ulw", "audio/basic");
+    mimeTypes.put("ustar", "application/x-ustar");
+    mimeTypes.put("xbm", "image/x-xbitmap");
+    mimeTypes.put("xht", "application/xhtml+xml");
+    mimeTypes.put("xhtml", "application/xhtml+xml");
+    mimeTypes.put("xml", "text/xml");
+    mimeTypes.put("xpm", "image/x-xpixmap");
+    mimeTypes.put("xsl", "text/xml");
+    mimeTypes.put("xwd", "image/x-xwindowdump");
+    mimeTypes.put("wav", "audio/x-wav");
+    mimeTypes.put("svg", "image/svg+xml");
+    mimeTypes.put("svgz", "image/svg+xml");
+    mimeTypes.put("vsd", "application/x-visio");
+    mimeTypes.put("wbmp", "image/vnd.wap.wbmp");
+    mimeTypes.put("wml", "text/vnd.wap.wml");
+    mimeTypes.put("wmlc", "application/vnd.wap.wmlc");
+    mimeTypes.put("wmls", "text/vnd.wap.wmlscript");
+    mimeTypes.put("wmlscriptc", "application/vnd.wap.wmlscriptc");
+    mimeTypes.put("wrl", "x-world/x-vrml");
+    mimeTypes.put("Z", "application/x-compress");
+    mimeTypes.put("z", "application/x-compress");
+    mimeTypes.put("zip", "application/zip");
+  }
+
+  /**
+   * Checks to see whether or not a client's file is out of date relative to the
+   * original.
+   */
+  private boolean isNotModified(HttpServletRequest request, long ageOfServerCopy) {
+    // The age of the server copy *must* have the milliseconds truncated.
+    // Since milliseconds isn't part of the GMT format, failure to truncate
+    // will leave the file in a state where it appears constantly out of date
+    // and yet it can never get in sync because the Last-Modified date keeps
+    // truncating off the milliseconds part on its way out.
+    // 
+    ageOfServerCopy -= (ageOfServerCopy % 1000);
+
+    long ageOfClientCopy = 0;
+    String ifModifiedSince = request.getHeader("If-Modified-Since");
+    if (ifModifiedSince != null) {
+      // Rip off any additional stuff at the end, such as "; length="
+      // (IE does add this).
+      //
+      int lastSemi = ifModifiedSince.lastIndexOf(';');
+      if (lastSemi != -1) {
+        ifModifiedSince = ifModifiedSince.substring(0, lastSemi);
+      }
+      ageOfClientCopy = HttpHeaders.fromInternetDateFormat(ifModifiedSince);
+    }
+
+    if (ageOfClientCopy >= ageOfServerCopy) {
+      // The client already has a good copy.
+      //
+      return true;
+    } else {
+      // The client needs a fresh copy of the requested file.
+      //
+      return false;
+    }
+  }
+
+  private void maybeIssueXhtmlWarning(TreeLogger logger, String mimeType,
+      String path) {
+    if (!XHTML_MIME_TYPE.equals(mimeType)) {
+      return;
+    }
+
+    String msg = "File was returned with content-type of \"" + mimeType
+        + "\". GWT requires browser features that are not available to "
+        + "documents with this content-type.";
+
+    int ix = path.lastIndexOf('.');
+    if (ix >= 0 && ix < path.length()) {
+      String base = path.substring(0, ix);
+      msg += " Consider renaming \"" + path + "\" to \"" + base + ".html\".";
+    }
+
+    logger.log(TreeLogger.WARN, msg, null);
+  }
+
+  private void sendErrorResponse(HttpServletResponse response, int statusCode,
+      String msg) throws IOException {
+    response.setContentType("text/html");
+    response.getWriter().println(msg);
+    response.setStatus(statusCode);
+  }
+
+  /**
+   * Sets the Cache-control and Expires headers in the response based on the
+   * supplied cache time.
+   * 
+   * Expires is used in addition to Cache-control for older clients or proxies
+   * which may not properly understand Cache-control.
+   * 
+   * @param response the HttpServletResponse to update
+   * @param cacheTime non-negative number of seconds to cache the response; 0
+   *          means specifically do not allow caching at all.
+   * @throws IllegalArgumentException if cacheTime is negative
+   */
+  private void setResponseCacheHeaders(HttpServletResponse response,
+      long cacheTime) {
+    long expires;
+    if (cacheTime < 0) {
+      throw new IllegalArgumentException("cacheTime of " + cacheTime
+          + " is negative");
+    }
+    if (cacheTime > 0) {
+      // Expire the specified seconds in the future.
+      expires = new Date().getTime() + cacheTime * HttpHeaders.MS_SEC;
+    } else {
+      // Prevent caching by using a time in the past for cache expiration.
+      // Use January 2, 1970 00:00:00, to account for timezone changes
+      // in case a browser tries to convert to a local timezone first
+      // 0=Jan 1, so add 1 day's worth of milliseconds to get Jan 2
+      expires = HttpHeaders.SEC_DAY * HttpHeaders.MS_SEC;
+    }
+    response.setHeader(HttpHeaders.CACHE_CONTROL,
+        HttpHeaders.CACHE_CONTROL_MAXAGE + cacheTime);
+    String expiresString = HttpHeaders.toInternetDateFormat(expires);
+    response.setHeader(HttpHeaders.EXPIRES, expiresString);
+  }
+
+  private boolean shouldAutoGenerateResources() {
+    ServletContext servletContext = getServletContext();
+    final String attr = "com.google.gwt.dev.shell.shouldAutoGenerateResources";
+    Boolean attrValue = (Boolean) servletContext.getAttribute(attr);
+    if (attrValue == null) {
+      return true;
+    }
+    return attrValue;
+  }
+
+  private void streamOut(InputStream in, OutputStream out, int bufferSize)
+      throws IOException {
+    assert (bufferSize >= 0);
+
+    byte[] buffer = new byte[bufferSize];
+    int bytesRead = 0;
+    while (true) {
+      bytesRead = in.read(buffer);
+      if (bytesRead >= 0) {
+        // Copy the bytes out.
+        out.write(buffer, 0, bytesRead);
+      } else {
+        // End of input stream.
+        out.flush();
+        return;
+      }
+    }
+  }
+
+  private HttpServlet tryGetOrLoadServlet(TreeLogger logger,
+      ModuleDef moduleDef, String className) {
+
+    // Maps className to live servlet for this module.
+    Map<String, HttpServlet> moduleServlets;
+    synchronized (loadedServletsByModuleAndClassName) {
+      moduleServlets = loadedServletsByModuleAndClassName.get(moduleDef);
+      if (moduleServlets == null) {
+        moduleServlets = new HashMap<String, HttpServlet>();
+        loadedServletsByModuleAndClassName.put(moduleDef, moduleServlets);
+      }
+    }
+
+    synchronized (moduleServlets) {
+      HttpServlet servlet = moduleServlets.get(className);
+      if (servlet != null) {
+        // Found it.
+        //
+        return servlet;
+      }
+
+      // Try to load and instantiate it.
+      //
+      Throwable caught = null;
+      try {
+        Class<?> servletClass = Class.forName(className);
+        Object newInstance = servletClass.newInstance();
+        if (!(newInstance instanceof HttpServlet)) {
+          logger.log(TreeLogger.ERROR,
+              "Not compatible with HttpServlet: " + className
+                  + " (does your service extend RemoteServiceServlet?)", null);
+          return null;
+        }
+
+        // Success. Hang onto the instance so we can reuse it.
+        //
+        servlet = (HttpServlet) newInstance;
+
+        // We create proxies for ServletContext and ServletConfig to enable
+        // RemoteServiceServlets to load public and generated resources via
+        // ServletContext.getResourceAsStream()
+        //
+        ServletContext context = new HostedModeServletContextProxy(
+            getServletContext(), moduleDef, getShellWorkDirs());
+        ServletConfig config = new HostedModeServletConfigProxy(
+            getServletConfig(), context);
+
+        servlet.init(config);
+
+        moduleServlets.put(className, servlet);
+        return servlet;
+      } catch (ClassNotFoundException e) {
+        caught = e;
+      } catch (InstantiationException e) {
+        caught = e;
+      } catch (IllegalAccessException e) {
+        caught = e;
+      } catch (ServletException e) {
+        caught = e;
+      }
+      String msg = "Unable to instantiate '" + className + "'";
+      logger.log(TreeLogger.ERROR, msg, caught);
+      return null;
+    }
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java b/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java
new file mode 100644
index 0000000..d6b321e
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/HostedModeServletContextProxy.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.resource.Resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * ServletContext proxy that implements the getResource and getResourceAsStream
+ * members so that they can work with the {@link GWTShellServlet}.
+ */
+class HostedModeServletContextProxy implements ServletContext {
+  private final ServletContext context;
+  /**
+   * Avoid pinning my moduleDef.
+   */
+  private final WeakReference<ModuleDef> moduleDefRef;
+  private final WorkDirs workDirs;
+
+  HostedModeServletContextProxy(ServletContext context, ModuleDef moduleDef,
+      WorkDirs workDirs) {
+    this.context = context;
+    this.moduleDefRef = new WeakReference<ModuleDef>(moduleDef);
+    this.workDirs = workDirs;
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+   */
+  public Object getAttribute(String arg0) {
+    return context.getAttribute(arg0);
+  }
+
+  /**
+   * @return
+   * @see javax.servlet.ServletContext#getAttributeNames()
+   */
+  @SuppressWarnings("unchecked")
+  public Enumeration<String> getAttributeNames() {
+    return context.getAttributeNames();
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getContext(java.lang.String)
+   */
+  public ServletContext getContext(String arg0) {
+    return context.getContext(arg0);
+  }
+
+  public String getContextPath() {
+    return context.getContextPath();
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+   */
+  public String getInitParameter(String arg0) {
+    return context.getInitParameter(arg0);
+  }
+
+  /**
+   * @return
+   * @see javax.servlet.ServletContext#getInitParameterNames()
+   */
+  public Enumeration<?> getInitParameterNames() {
+    return context.getInitParameterNames();
+  }
+
+  /**
+   * @return
+   * @see javax.servlet.ServletContext#getMajorVersion()
+   */
+  public int getMajorVersion() {
+    return context.getMajorVersion();
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getMimeType(java.lang.String)
+   */
+  public String getMimeType(String arg0) {
+    return context.getMimeType(arg0);
+  }
+
+  /**
+   * @return
+   * @see javax.servlet.ServletContext#getMinorVersion()
+   */
+  public int getMinorVersion() {
+    return context.getMinorVersion();
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
+   */
+  public RequestDispatcher getNamedDispatcher(String arg0) {
+    return context.getNamedDispatcher(arg0);
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getRealPath(java.lang.String)
+   */
+  public String getRealPath(String arg0) {
+    return context.getRealPath(arg0);
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String)
+   */
+  public RequestDispatcher getRequestDispatcher(String arg0) {
+    return context.getRequestDispatcher(arg0);
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @throws MalformedURLException
+   * @see javax.servlet.ServletContext#getResource(java.lang.String)
+   */
+  @SuppressWarnings("deprecation")
+  public URL getResource(String path) throws MalformedURLException {
+    ModuleDef moduleDef = moduleDefRef.get();
+    assert (moduleDef != null) : "GWTShellServlet should have guaranteed that a"
+        + " live servlet will never process a request for a dead module; if you"
+        + " are using this servlet outside the context of processing a call,"
+        + " then don't do that";
+
+    String moduleContext = "/" + moduleDef.getName() + "/";
+    if (!path.startsWith(moduleContext)) {
+      // Check for a renamed module
+      moduleContext = "/" + moduleDef.getCanonicalName() + "/";
+      if (!path.startsWith(moduleContext)) {
+        // This path is in a different context; just return null
+        return null;
+      }
+    }
+
+    String partialPath = path.substring(moduleContext.length());
+
+    // Try to get the resource from the application's public path
+    Resource publicResource = moduleDef.findPublicFile(partialPath);
+    if (publicResource != null) {
+      return publicResource.getURL();
+    }
+
+    // Otherwise try the path in the shell's public generated directory
+    File shellDir = workDirs.getShellPublicGenDir(moduleDef);
+    File requestedFile = new File(shellDir, partialPath);
+    if (requestedFile.exists()) {
+      return requestedFile.toURI().toURL();
+    }
+
+    /*
+     * If the user is coming from compiled web-mode, check the linker output
+     * directory for the file. We'll default to using the output directory of
+     * the first linker defined in the <set-linker> tab.
+     */
+    File linkDir = workDirs.getCompilerOutputDir(moduleDef);
+    requestedFile = new File(linkDir, partialPath);
+    if (requestedFile.exists()) {
+      try {
+        return requestedFile.toURI().toURL();
+      } catch (MalformedURLException e) {
+        // ignore since it was speculative anyway
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String)
+   */
+  public InputStream getResourceAsStream(String arg0) {
+    URL url;
+    try {
+      url = getResource(arg0);
+      if (url != null) {
+        return url.openStream();
+      }
+    } catch (MalformedURLException e) {
+      // Ignore the exception; return null
+    } catch (IOException e) {
+      // Ignore the exception; return null
+    }
+
+    return null;
+  }
+
+  /**
+   * 
+   * @param path
+   * @return
+   * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
+   */
+  @SuppressWarnings("unchecked")
+  public Set<String> getResourcePaths(String path) {
+    return context.getResourcePaths(path);
+  }
+
+  /**
+   * @return
+   * @see javax.servlet.ServletContext#getServerInfo()
+   */
+  public String getServerInfo() {
+    return context.getServerInfo();
+  }
+
+  /**
+   * @param arg0
+   * @return
+   * @throws ServletException
+   * @deprecated
+   * @see javax.servlet.ServletContext#getServlet(java.lang.String)
+   */
+  @Deprecated
+  public Servlet getServlet(String arg0) throws ServletException {
+    return context.getServlet(arg0);
+  }
+
+  /**
+   * @return
+   * @see javax.servlet.ServletContext#getServletContextName()
+   */
+  public String getServletContextName() {
+    return context.getServletContextName();
+  }
+
+  /**
+   * @return
+   * @deprecated
+   * @see javax.servlet.ServletContext#getServletNames()
+   */
+  @Deprecated
+  @SuppressWarnings("unchecked")
+  public Enumeration<String> getServletNames() {
+    return context.getServletNames();
+  }
+
+  /**
+   * @return
+   * @deprecated
+   * @see javax.servlet.ServletContext#getServlets()
+   */
+  @Deprecated
+  @SuppressWarnings("unchecked")
+  public Enumeration<Servlet> getServlets() {
+    return context.getServlets();
+  }
+
+  /**
+   * @param arg0
+   * @param arg1
+   * @deprecated
+   * @see javax.servlet.ServletContext#log(java.lang.Exception,
+   *      java.lang.String)
+   */
+  @Deprecated
+  public void log(Exception arg0, String arg1) {
+    context.log(arg0, arg1);
+  }
+
+  /**
+   * @param arg0
+   * @see javax.servlet.ServletContext#log(java.lang.String)
+   */
+  public void log(String arg0) {
+    context.log(arg0);
+  }
+
+  /**
+   * @param arg0
+   * @param arg1
+   * @see javax.servlet.ServletContext#log(java.lang.String,java.lang.Throwable)
+   */
+  public void log(String arg0, Throwable arg1) {
+    context.log(arg0, arg1);
+  }
+
+  /**
+   * @param arg0
+   * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
+   */
+  public void removeAttribute(String arg0) {
+    context.removeAttribute(arg0);
+  }
+
+  /**
+   * @param arg0
+   * @param arg1
+   * @see javax.servlet.ServletContext#setAttribute(java.lang.String,java.lang.Object)
+   */
+  public void setAttribute(String arg0, Object arg1) {
+    context.setAttribute(arg0, arg1);
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/CatalinaLoggerAdapter.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/CatalinaLoggerAdapter.java
new file mode 100644
index 0000000..9cf2d95
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/tomcat/CatalinaLoggerAdapter.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2006 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev.shell.tomcat;
+
+import com.google.gwt.core.ext.TreeLogger;
+
+import org.apache.catalina.logger.LoggerBase;
+
+class CatalinaLoggerAdapter extends LoggerBase {
+
+  private final TreeLogger logger;
+
+  public CatalinaLoggerAdapter(TreeLogger logger) {
+    this.logger = logger;
+  }
+
+  @Override
+  public void log(Exception exception, String msg) {
+    logger.log(TreeLogger.WARN, msg, exception);
+  }
+
+  @Override
+  public void log(String msg) {
+    logger.log(TreeLogger.INFO, msg, null);
+  }
+
+  @Override
+  public void log(String message, int verbosity) {
+    TreeLogger.Type type = mapVerbosityToLogType(verbosity);
+    logger.log(type, message, null);
+  }
+
+  @Override
+  public void log(String msg, Throwable throwable) {
+    logger.log(TreeLogger.WARN, msg, throwable);
+  }
+
+  @Override
+  public void log(String message, Throwable throwable, int verbosity) {
+    TreeLogger.Type type = mapVerbosityToLogType(verbosity);
+    logger.log(type, message, throwable);
+  }
+
+  private TreeLogger.Type mapVerbosityToLogType(int verbosity) {
+    switch (verbosity) {
+      case LoggerBase.FATAL:
+      case LoggerBase.ERROR:
+      case LoggerBase.WARNING:
+        return TreeLogger.WARN;
+
+      case LoggerBase.INFORMATION:
+        return TreeLogger.DEBUG;
+      case LoggerBase.DEBUG:
+        return TreeLogger.SPAM;
+
+      default:
+        // really, this was an unexpected type
+        return TreeLogger.WARN;
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/dev/shell/tomcat/CommonsLoggerAdapter.java b/dev/core/src/com/google/gwt/dev/shell/tomcat/CommonsLoggerAdapter.java
new file mode 100644
index 0000000..d071d2a
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/tomcat/CommonsLoggerAdapter.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2006 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev.shell.tomcat;
+
+import com.google.gwt.core.ext.TreeLogger;
+
+/**
+ * Maps Tomcat's commons logger onto the GWT shell's tree logger.
+ */
+public class CommonsLoggerAdapter implements org.apache.commons.logging.Log {
+
+  private TreeLogger log;
+
+  /**
+   * @param name unused
+   */
+  public CommonsLoggerAdapter(String name) {
+    // NOTE: this is ugly, but I don't know of any other way to get a
+    // non-static log to which we can delegate.
+    //
+    log = EmbeddedTomcatServer.sTomcat.getLogger();
+  }
+
+  public void debug(Object message) {
+    doLog(TreeLogger.SPAM, message, null);
+  }
+
+  public void debug(Object message, Throwable t) {
+    doLog(TreeLogger.SPAM, message, t);
+  }
+
+  public void error(Object message) {
+    doLog(TreeLogger.WARN, message, null);
+  }
+
+  public void error(Object message, Throwable t) {
+    doLog(TreeLogger.WARN, message, t);
+  }
+
+  public void fatal(Object message) {
+    doLog(TreeLogger.WARN, message, null);
+  }
+
+  public void fatal(Object message, Throwable t) {
+    doLog(TreeLogger.WARN, message, t);
+  }
+
+  public void info(Object message) {
+    // Intentionally low-level to us.
+    doLog(TreeLogger.TRACE, message, null);
+  }
+
+  public void info(Object message, Throwable t) {
+    // Intentionally low-level to us.
+    doLog(TreeLogger.TRACE, message, t);
+  }
+
+  public boolean isDebugEnabled() {
+    return log.isLoggable(TreeLogger.SPAM);
+  }
+
+  public boolean isErrorEnabled() {
+    return log.isLoggable(TreeLogger.WARN);
+  }
+
+  public boolean isFatalEnabled() {
+    return log.isLoggable(TreeLogger.WARN);
+  }
+
+  public boolean isInfoEnabled() {
+    // Intentionally low-level to us.
+    return log.isLoggable(TreeLogger.TRACE);
+  }
+
+  public boolean isTraceEnabled() {
+    // Intentionally low-level to us.
+    return log.isLoggable(TreeLogger.SPAM);
+  }
+
+  public boolean isWarnEnabled() {
+    return log.isLoggable(TreeLogger.WARN);
+  }
+
+  public void trace(Object message) {
+    // Intentionally low-level to us.
+    doLog(TreeLogger.DEBUG, message, null);
+  }
+
+  public void trace(Object message, Throwable t) {
+    // Intentionally low-level to us.
+    doLog(TreeLogger.DEBUG, message, t);
+  }
+
+  public void warn(Object message) {
+    doLog(TreeLogger.WARN, message, null);
+  }
+
+  public void warn(Object message, Throwable t) {
+    doLog(TreeLogger.WARN, message, t);
+  }
+
+  private void doLog(TreeLogger.Type type, Object message, Throwable t) {
+    String msg = message.toString();
+    log.log(type, msg, t);
+  }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..e7d27ac
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/tomcat/EmbeddedTomcatServer.java
@@ -0,0 +1,436 @@
+/*
+ * Copyright 2006 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev.shell.tomcat;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.dev.resource.impl.ClassPathEntry;
+import com.google.gwt.dev.resource.impl.PathPrefix;
+import com.google.gwt.dev.resource.impl.PathPrefixSet;
+import com.google.gwt.dev.resource.impl.ResourceOracleImpl;
+import com.google.gwt.dev.shell.WorkDirs;
+import com.google.gwt.dev.util.Util;
+
+import org.apache.catalina.Connector;
+import org.apache.catalina.ContainerEvent;
+import org.apache.catalina.ContainerListener;
+import org.apache.catalina.Engine;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.Logger;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.startup.Embedded;
+import org.apache.catalina.startup.HostConfig;
+import org.apache.coyote.tomcat5.CoyoteConnector;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Wraps an instance of the Tomcat web server used in hosted mode.
+ */
+public class EmbeddedTomcatServer {
+
+  static EmbeddedTomcatServer sTomcat;
+
+  public static int getPort() {
+    return sTomcat.port;
+  }
+
+  public static String start(TreeLogger topLogger, int port, WorkDirs workDirs) {
+    return start(topLogger, port, workDirs, true);
+  }
+
+  public static synchronized String start(TreeLogger topLogger, int port,
+      WorkDirs workDirs, boolean shouldAutoGenerateResources) {
+    if (sTomcat != null) {
+      throw new IllegalStateException("Embedded Tomcat is already running");
+    }
+
+    try {
+      new EmbeddedTomcatServer(topLogger, port, workDirs,
+          shouldAutoGenerateResources);
+      return null;
+    } catch (LifecycleException e) {
+      String msg = e.getMessage();
+      if (msg != null && msg.indexOf("already in use") != -1) {
+        msg = "Port "
+            + port
+            + " is already is use; you probably still have another session active";
+      } else {
+        msg = "Unable to start the embedded Tomcat server; double-check that your configuration is valid";
+      }
+      return msg;
+    }
+  }
+
+  // Stop the embedded Tomcat server.
+  //
+  public static synchronized void stop() {
+    if (sTomcat != null) {
+      try {
+        sTomcat.catEmbedded.stop();
+      } catch (LifecycleException e) {
+        // There's nothing we can really do about this and the logger is
+        // gone in many scenarios, so we just ignore it.
+        //
+      } finally {
+        sTomcat = null;
+      }
+    }
+  }
+
+  /**
+   * Returns what local port the Tomcat connector is running on.
+   * 
+   * When starting Tomcat with port 0 (i.e. choose an open port), there is just
+   * no way to figure out what port it actually chose. So we're using pure
+   * hackery to steal the port via reflection. The only works because we bundle
+   * Tomcat with GWT and know exactly what version it is.
+   */
+  private static int computeLocalPort(Connector connector) {
+    Throwable caught = null;
+    try {
+      Field phField = CoyoteConnector.class.getDeclaredField("protocolHandler");
+      phField.setAccessible(true);
+      Object protocolHandler = phField.get(connector);
+
+      Field epField = protocolHandler.getClass().getDeclaredField("ep");
+      epField.setAccessible(true);
+      Object endPoint = epField.get(protocolHandler);
+
+      Field ssField = endPoint.getClass().getDeclaredField("serverSocket");
+      ssField.setAccessible(true);
+      ServerSocket serverSocket = (ServerSocket) ssField.get(endPoint);
+
+      return serverSocket.getLocalPort();
+    } catch (SecurityException e) {
+      caught = e;
+    } catch (NoSuchFieldException e) {
+      caught = e;
+    } catch (IllegalArgumentException e) {
+      caught = e;
+    } catch (IllegalAccessException e) {
+      caught = e;
+    }
+    throw new RuntimeException(
+        "Failed to retrieve the startup port from Embedded Tomcat", caught);
+  }
+
+  private Embedded catEmbedded;
+
+  private Engine catEngine;
+
+  private StandardHost catHost = null;
+
+  private int port;
+
+  private final TreeLogger startupBranchLogger;
+
+  private EmbeddedTomcatServer(final TreeLogger topLogger, int listeningPort,
+      final WorkDirs workDirs, final boolean shouldAutoGenerateResources)
+      throws LifecycleException {
+    if (topLogger == null) {
+      throw new NullPointerException("No logger specified");
+    }
+
+    final TreeLogger logger = topLogger.branch(TreeLogger.INFO,
+        "Starting HTTP on port " + listeningPort, null);
+
+    startupBranchLogger = logger;
+
+    // Make myself the one static instance.
+    // NOTE: there is only one small implementation reason that this has
+    // to be a singleton, which is that the commons logger LogFactory insists
+    // on creating your logger class which must have a constructor with
+    // exactly one String argument, and since we want LoggerAdapter to delegate
+    // to the logger instance available through instance host, there is no
+    // way I can think of to delegate without accessing a static field.
+    // An inner class is almost right, except there's no outer instance.
+    //
+    sTomcat = this;
+
+    // Assume the working directory is simply the user's current directory.
+    //
+    File topWorkDir = new File(System.getProperty("user.dir"));
+
+    // Tell Tomcat its base directory so that it won't complain.
+    //
+    String catBase = System.getProperty("catalina.base");
+    if (catBase == null) {
+      // we (briefly) supported catalina.base.create, so let's not cut support
+      // until the deprecated sunset
+      catBase = System.getProperty("catalina.base.create");
+      if (catBase != null) {
+        logger.log(TreeLogger.WARN, "catalina.base.create is deprecated.  " +
+            "Use catalina.base, and it will be created if necessary.");
+        topWorkDir = new File(catBase);
+      }
+      catBase = generateDefaultCatalinaBase(logger, topWorkDir);
+      System.setProperty("catalina.base", catBase);
+    }
+
+    // Some debug messages for ourselves.
+    //
+    if (logger.isLoggable(TreeLogger.DEBUG)) {
+      logger.log(TreeLogger.DEBUG, "catalina.base = " + catBase, null);
+    }
+
+    // Set up the logger that will be returned by the Commons logging factory.
+    //
+    String adapterClassName = CommonsLoggerAdapter.class.getName();
+    System.setProperty("org.apache.commons.logging.Log", adapterClassName);
+
+    // And set up an adapter that will work with the Catalina logger family.
+    //
+    Logger catalinaLogger = new CatalinaLoggerAdapter(topLogger);
+
+    // Create an embedded server.
+    //
+    catEmbedded = new Embedded();
+    catEmbedded.setDebug(0);
+    catEmbedded.setLogger(catalinaLogger);
+
+    // The embedded engine is called "gwt".
+    //
+    catEngine = catEmbedded.createEngine();
+    catEngine.setName("gwt");
+    catEngine.setDefaultHost("localhost");
+    catEngine.setParentClassLoader(this.getClass().getClassLoader());
+
+    // It answers localhost requests.
+    //
+    // String appBase = fCatalinaBaseDir.getAbsolutePath();
+    String appBase = catBase + "/webapps";
+    catHost = (StandardHost) catEmbedded.createHost("localhost", appBase);
+
+    // Hook up a host config to search for and pull in webapps.
+    //
+    HostConfig hostConfig = new HostConfig();
+    catHost.addLifecycleListener(hostConfig);
+
+    // Hook pre-install events so that we can add attributes to allow loaded
+    // instances to find their development instance host.
+    //
+    catHost.addContainerListener(new ContainerListener() {
+      public void containerEvent(ContainerEvent event) {
+        if (StandardHost.PRE_INSTALL_EVENT.equals(event.getType())) {
+          StandardContext webapp = (StandardContext) event.getData();
+          publishShellLoggerAttribute(logger, topLogger, webapp);
+          publishShellWorkDirsAttribute(logger, workDirs, webapp);
+          publishShouldAutoGenerateResourcesAttribute(logger,
+              shouldAutoGenerateResources, webapp);
+        }
+      }
+    });
+
+    // Tell the engine about the host.
+    //
+    catEngine.addChild(catHost);
+    catEngine.setDefaultHost(catHost.getName());
+
+    // Tell the embedded manager about the engine.
+    //
+    catEmbedded.addEngine(catEngine);
+    InetAddress nullAddr = null;
+    Connector connector = catEmbedded.createConnector(nullAddr, listeningPort,
+        false);
+    catEmbedded.addConnector(connector);
+
+    // start up!
+    catEmbedded.start();
+    port = computeLocalPort(connector);
+
+    if (port != listeningPort) {
+      if (logger.isLoggable(TreeLogger.INFO)) {
+        logger.log(TreeLogger.INFO, "HTTP listening on port " + port, null);
+      }
+    }
+  }
+
+  public TreeLogger getLogger() {
+    return startupBranchLogger;
+  }
+
+  /*
+   * Assumes that the leaf is a file (not a directory).
+   */
+  private void copyFileNoOverwrite(TreeLogger logger, String srcResName,
+      Resource srcRes, File catBase) {
+
+    File dest = new File(catBase, srcResName);
+    try {
+      // Only copy if src is newer than desc.
+      long srcLastModified = srcRes.getLastModified();
+      long dstLastModified = dest.lastModified();
+
+      if (srcLastModified < dstLastModified) {
+        // Don't copy over it.
+        if (logger.isLoggable(TreeLogger.SPAM)) {
+          logger.log(TreeLogger.SPAM, "Source is older than existing: "
+              + dest.getAbsolutePath(), null);
+        }
+        return;
+      } else if (srcLastModified == dstLastModified) {
+        // Exact same time; quietly don't overwrite.
+        return;
+      } else if (dest.exists()) {
+        // Warn about the overwrite
+        logger.log(TreeLogger.WARN, "Overwriting existing file '"
+            + dest.getAbsolutePath() + "' with '" + srcRes.getLocation()
+            + "', which has a newer timestamp");
+      }
+
+      // Make dest directories as required.
+      File destParent = dest.getParentFile();
+      if (destParent != null) {
+        // No need to check mkdirs result because IOException later anyway.
+        destParent.mkdirs();
+      }
+
+      Util.copy(srcRes.openContents(), new FileOutputStream(dest));
+      dest.setLastModified(srcLastModified);
+
+      if (logger.isLoggable(TreeLogger.TRACE)) {
+        logger.log(TreeLogger.TRACE, "Wrote: " + dest.getAbsolutePath(), null);
+      }
+    } catch (IOException e) {
+      logger.log(TreeLogger.WARN, "Failed to write: " + dest.getAbsolutePath(),
+          e);
+    } 
+  }
+
+  /**
+   * Extracts a valid catalina base instance from the classpath. Does not
+   * overwrite any existing files.
+   */
+  private String generateDefaultCatalinaBase(TreeLogger logger, File workDir) {
+    logger = logger.branch(
+        TreeLogger.TRACE,
+        "Property 'catalina.base' not specified; checking for a standard catalina base image instead",
+        null);
+
+    // Recursively copies out files and directories
+    String tomcatEtcDir = "com/google/gwt/dev/etc/tomcat/";
+    Map<String, Resource> resourceMap = null;
+    Throwable caught = null;
+    try {
+      resourceMap = getResourcesFor(logger, tomcatEtcDir);
+    } catch (URISyntaxException e) {
+      caught = e;
+    } catch (IOException e) {
+      caught = e;
+    }
+
+    File catBase = new File(workDir, "tomcat");
+    if (resourceMap == null || resourceMap.isEmpty()) {
+      logger.log(TreeLogger.WARN, "Could not find " + tomcatEtcDir, caught);
+    } else {
+      for (Entry<String, Resource> entry : resourceMap.entrySet()) {
+        copyFileNoOverwrite(logger, entry.getKey(), entry.getValue(), catBase);
+      }
+    }
+
+    return catBase.getAbsolutePath();
+  }
+
+  /**
+   * Hacky, but fast.
+   */
+  private Map<String, Resource> getResourcesFor(TreeLogger logger,
+      String tomcatEtcDir) throws URISyntaxException, IOException {
+    ClassLoader contextClassLoader = this.getClass().getClassLoader();
+    URL url = contextClassLoader.getResource(tomcatEtcDir);
+    if (url == null) {
+      return null;
+    }
+    String prefix = "";
+    String urlString = url.toString();
+    if (urlString.startsWith("jar:")) {
+      assert urlString.toLowerCase(Locale.ENGLISH).contains(".jar!/"
+          + tomcatEtcDir);
+      urlString = urlString.substring(4, urlString.indexOf('!'));
+      url = new URL(urlString);
+      prefix = tomcatEtcDir;
+    } else if (urlString.startsWith("zip:")) {
+      assert urlString.toLowerCase(Locale.ENGLISH).contains(".zip!/"
+          + tomcatEtcDir);
+      urlString = urlString.substring(4, urlString.indexOf('!'));
+      url = new URL(urlString);
+      prefix = tomcatEtcDir;
+    }
+    ClassPathEntry entry = ResourceOracleImpl.createEntryForUrl(logger, url);
+    assert (entry != null);
+    ResourceOracleImpl resourceOracle = new ResourceOracleImpl(
+        Collections.singletonList(entry));
+    PathPrefixSet pathPrefixSet = new PathPrefixSet();
+    PathPrefix pathPrefix = new PathPrefix(prefix, null, true);
+    pathPrefixSet.add(pathPrefix);
+    resourceOracle.setPathPrefixes(pathPrefixSet);
+    ResourceOracleImpl.refresh(logger, resourceOracle);
+    Map<String, Resource> resourceMap = resourceOracle.getResourceMap();
+    return resourceMap;
+  }
+
+  private void publishAttributeToWebApp(TreeLogger logger,
+      StandardContext webapp, String attrName, Object attrValue) {
+    if (logger.isLoggable(TreeLogger.TRACE)) {
+      logger.log(TreeLogger.TRACE, "Adding attribute  '" + attrName
+          + "' to web app '" + webapp.getName() + "'", null);
+    }
+    webapp.getServletContext().setAttribute(attrName, attrValue);
+  }
+
+  /**
+   * Publish the shell's tree logger as an attribute. This attribute is used to
+   * find the logger out of the thin air within the shell servlet.
+   */
+  private void publishShellLoggerAttribute(TreeLogger logger,
+      TreeLogger loggerToPublish, StandardContext webapp) {
+    final String attr = "com.google.gwt.dev.shell.logger";
+    publishAttributeToWebApp(logger, webapp, attr, loggerToPublish);
+  }
+
+  /**
+   * Publish the shell's work dir as an attribute. This attribute is used to
+   * find it out of the thin air within the shell servlet.
+   */
+  private void publishShellWorkDirsAttribute(TreeLogger logger,
+      WorkDirs workDirs, StandardContext webapp) {
+    final String attr = "com.google.gwt.dev.shell.workdirs";
+    publishAttributeToWebApp(logger, webapp, attr, workDirs);
+  }
+
+  /**
+   * Publish to the web app whether it should automatically generate resources.
+   */
+  private void publishShouldAutoGenerateResourcesAttribute(TreeLogger logger,
+      boolean shouldAutoGenerateResources, StandardContext webapp) {
+    publishAttributeToWebApp(logger, webapp,
+        "com.google.gwt.dev.shell.shouldAutoGenerateResources",
+        shouldAutoGenerateResources);
+  }
+}
diff --git a/dev/core/src/org/apache/COPYING b/dev/core/src/org/apache/COPYING
new file mode 100644
index 0000000..d9a10c0
--- /dev/null
+++ b/dev/core/src/org/apache/COPYING
@@ -0,0 +1,176 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
diff --git a/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java b/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java
new file mode 100644
index 0000000..f941fad
--- /dev/null
+++ b/dev/core/src/org/apache/catalina/loader/WebappClassLoader.java
@@ -0,0 +1,2169 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes.Name;
+
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.util.StringManager;
+import org.apache.naming.JndiPermission;
+import org.apache.naming.resources.Resource;
+import org.apache.naming.resources.ResourceAttributes;
+import org.apache.tomcat.util.compat.JdkCompat;
+
+/**
+ * Specialized web application class loader.
+ * <p>
+ * This class loader is a full reimplementation of the 
+ * <code>URLClassLoader</code> from the JDK. It is desinged to be fully
+ * compatible with a normal <code>URLClassLoader</code>, although its internal
+ * behavior may be completely different.
+ * <p>
+ * <strong>IMPLEMENTATION NOTE</strong> - This class loader faithfully follows 
+ * the delegation model recommended in the specification. The system class 
+ * loader will be queried first, then the local repositories, and only then 
+ * delegation to the parent class loader will occur. This allows the web 
+ * application to override any shared class except the classes from J2SE.
+ * Special handling is provided from the JAXP XML parser interfaces, the JNDI
+ * interfaces, and the classes from the servlet API, which are never loaded 
+ * from the webapp repository.
+ * <p>
+ * <strong>IMPLEMENTATION NOTE</strong> - Due to limitations in Jasper 
+ * compilation technology, any repository which contains classes from 
+ * the servlet API will be ignored by the class loader.
+ * <p>
+ * <strong>IMPLEMENTATION NOTE</strong> - The class loader generates source
+ * URLs which include the full JAR URL when a class is loaded from a JAR file,
+ * which allows setting security permission at the class level, even when a
+ * class is contained inside a JAR.
+ * <p>
+ * <strong>IMPLEMENTATION NOTE</strong> - Local repositories are searched in
+ * the order they are added via the initial constructor and/or any subsequent
+ * calls to <code>addRepository()</code> or <code>addJar()</code>.
+ * <p>
+ * <strong>IMPLEMENTATION NOTE</strong> - No check for sealing violations or
+ * security is made unless a security manager is present.
+ *
+ * @author Remy Maucherat
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.34 $ $Date: 2004/05/26 15:47:40 $
+ */
+public class WebappClassLoader
+    extends URLClassLoader
+    implements Reloader, Lifecycle
+ {
+
+    private static org.apache.commons.logging.Log log=
+        org.apache.commons.logging.LogFactory.getLog( WebappClassLoader.class );
+
+    protected class PrivilegedFindResource
+        implements PrivilegedAction {
+
+        private File file;
+        private String path;
+
+        PrivilegedFindResource(File file, String path) {
+            this.file = file;
+            this.path = path;
+        }
+
+        public Object run() {
+            return findResourceInternal(file, path);
+        }
+
+    }
+
+
+    // ------------------------------------------------------- Static Variables
+
+
+    /**
+     * The set of trigger classes that will cause a proposed repository not
+     * to be added if this class is visible to the class loader that loaded
+     * this factory class.  Typically, trigger classes will be listed for
+     * components that have been integrated into the JDK for later versions,
+     * but where the corresponding JAR files are required to run on
+     * earlier versions.
+     */
+    private static final String[] triggers = {
+        "javax.servlet.Servlet"                     // Servlet API
+    };
+
+    /** 
+     * Jdk Compatibility Support.
+     */
+    private static JdkCompat jdkCompat = JdkCompat.getJdkCompat();
+
+    /**
+     * Set of package names which are not allowed to be loaded from a webapp
+     * class loader without delegating first.
+     */
+    private static final String[] packageTriggers = {
+        "javax",                                     // Java extensions
+        "org.xml.sax",                               // SAX 1 & 2
+        "org.w3c.dom",                               // DOM 1 & 2
+        "org.apache.xerces",                         // Xerces 1 & 2
+        "org.apache.xalan"                           // Xalan
+    };
+
+
+    /**
+     * The string manager for this package.
+     */
+    protected static final StringManager sm =
+        StringManager.getManager(Constants.Package);
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Construct a new ClassLoader with no defined repositories and no
+     * parent ClassLoader.
+     */
+    public WebappClassLoader() {
+
+        super(new URL[0]);
+        this.parent = getParent();
+        system = getSystemClassLoader();
+        securityManager = System.getSecurityManager();
+
+        if (securityManager != null) {
+            refreshPolicy();
+        }
+
+    }
+
+
+    /**
+     * Construct a new ClassLoader with no defined repositories and no
+     * parent ClassLoader.
+     */
+    public WebappClassLoader(ClassLoader parent) {
+
+        super(new URL[0], parent);
+                
+        this.parent = getParent();
+        
+        system = getSystemClassLoader();
+        securityManager = System.getSecurityManager();
+
+        if (securityManager != null) {
+            refreshPolicy();
+        }
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Associated directory context giving access to the resources in this
+     * webapp.
+     */
+    protected DirContext resources = null;
+
+
+    /**
+     * The cache of ResourceEntry for classes and resources we have loaded,
+     * keyed by resource name.
+     */
+    protected HashMap resourceEntries = new HashMap();
+
+
+    /**
+     * The list of not found resources.
+     */
+    protected HashMap notFoundResources = new HashMap();
+
+
+    /**
+     * The debugging detail level of this component.
+     */
+    protected int debug = 0;
+
+
+    /**
+     * Should this class loader delegate to the parent class loader
+     * <strong>before</strong> searching its own repositories (i.e. the
+     * usual Java2 delegation model)?  If set to <code>false</code>,
+     * this class loader will search its own repositories first, and
+     * delegate to the parent only if the class or resource is not
+     * found locally.
+     */
+    protected boolean delegate = false;
+
+
+    /**
+     * Last time a JAR was accessed.
+     */
+    protected long lastJarAccessed = 0L;
+
+
+    /**
+     * The list of local repositories, in the order they should be searched
+     * for locally loaded classes or resources.
+     */
+    protected String[] repositories = new String[0];
+
+
+     /**
+      * Repositories URLs, used to cache the result of getURLs.
+      */
+     protected URL[] repositoryURLs = null;
+
+
+    /**
+     * Repositories translated as path in the work directory (for Jasper
+     * originally), but which is used to generate fake URLs should getURLs be
+     * called.
+     */
+    protected File[] files = new File[0];
+
+
+    /**
+     * The list of JARs, in the order they should be searched
+     * for locally loaded classes or resources.
+     */
+    protected JarFile[] jarFiles = new JarFile[0];
+
+
+    /**
+     * The list of JARs, in the order they should be searched
+     * for locally loaded classes or resources.
+     */
+    protected File[] jarRealFiles = new File[0];
+
+
+    /**
+     * The path which will be monitored for added Jar files.
+     */
+    protected String jarPath = null;
+
+
+    /**
+     * The list of JARs, in the order they should be searched
+     * for locally loaded classes or resources.
+     */
+    protected String[] jarNames = new String[0];
+
+
+    /**
+     * The list of JARs last modified dates, in the order they should be
+     * searched for locally loaded classes or resources.
+     */
+    protected long[] lastModifiedDates = new long[0];
+
+
+    /**
+     * The list of resources which should be checked when checking for
+     * modifications.
+     */
+    protected String[] paths = new String[0];
+
+
+    /**
+     * A list of read File and Jndi Permission's required if this loader
+     * is for a web application context.
+     */
+    private ArrayList permissionList = new ArrayList();
+
+
+    /**
+     * Path where resources loaded from JARs will be extracted.
+     */
+    private File loaderDir = null;
+
+
+    /**
+     * The PermissionCollection for each CodeSource for a web
+     * application context.
+     */
+    private HashMap loaderPC = new HashMap();
+
+
+    /**
+     * Instance of the SecurityManager installed.
+     */
+    private SecurityManager securityManager = null;
+
+
+    /**
+     * The parent class loader.
+     */
+    private ClassLoader parent = null;
+
+
+    /**
+     * The system class loader.
+     */
+    private ClassLoader system = null;
+
+
+    /**
+     * Has this component been started?
+     */
+    protected boolean started = false;
+
+
+    /**
+     * Has external repositories.
+     */
+    protected boolean hasExternalRepositories = false;
+
+
+    /**
+     * All permission.
+     */
+    private Permission allPermission = new java.security.AllPermission();
+
+
+    // ------------------------------------------------------------- Properties
+
+
+    /**
+     * Get associated resources.
+     */
+    public DirContext getResources() {
+
+        return this.resources;
+
+    }
+
+
+    /**
+     * Set associated resources.
+     */
+    public void setResources(DirContext resources) {
+
+        this.resources = resources;
+
+    }
+
+
+    /**
+     * 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) {
+
+        this.debug = debug;
+
+    }
+
+
+    /**
+     * Return the "delegate first" flag for this class loader.
+     */
+    public boolean getDelegate() {
+
+        return (this.delegate);
+
+    }
+
+
+    /**
+     * Set the "delegate first" flag for this class loader.
+     *
+     * @param delegate The new "delegate first" flag
+     */
+    public void setDelegate(boolean delegate) {
+
+        this.delegate = delegate;
+
+    }
+
+
+    /**
+     * If there is a Java SecurityManager create a read FilePermission
+     * or JndiPermission for the file directory path.
+     *
+     * @param path file directory path
+     */
+    public void addPermission(String path) {
+        if (path == null) {
+            return;
+        }
+
+        if (securityManager != null) {
+            Permission permission = null;
+            if( path.startsWith("jndi:") || path.startsWith("jar:jndi:") ) {
+                if (!path.endsWith("/")) {
+                    path = path + "/";
+                }
+                permission = new JndiPermission(path + "*");
+                addPermission(permission);
+            } else {
+                if (!path.endsWith(File.separator)) {
+                    permission = new FilePermission(path, "read");
+                    addPermission(permission);
+                    path = path + File.separator;
+                }
+                permission = new FilePermission(path + "-", "read");
+                addPermission(permission);
+            }
+        }
+    }
+
+
+    /**
+     * If there is a Java SecurityManager create a read FilePermission
+     * or JndiPermission for URL.
+     *
+     * @param url URL for a file or directory on local system
+     */
+    public void addPermission(URL url) {
+        if (url != null) {
+            addPermission(url.toString());
+        }
+    }
+
+
+    /**
+     * If there is a Java SecurityManager create a Permission.
+     *
+     * @param url URL for a file or directory on local system
+     */
+    public void addPermission(Permission permission) {
+        if ((securityManager != null) && (permission != null)) {
+            permissionList.add(permission);
+        }
+    }
+
+
+    /**
+     * Return the JAR path.
+     */
+    public String getJarPath() {
+
+        return this.jarPath;
+
+    }
+
+
+    /**
+     * Change the Jar path.
+     */
+    public void setJarPath(String jarPath) {
+
+        this.jarPath = jarPath;
+
+    }
+
+
+    /**
+     * Change the work directory.
+     */
+    public void setWorkDir(File workDir) {
+        this.loaderDir = new File(workDir, "loader");
+    }
+
+
+    // ------------------------------------------------------- Reloader Methods
+
+
+    /**
+     * Add a new repository to the set of places this ClassLoader can look for
+     * classes to be loaded.
+     *
+     * @param repository Name of a source of classes to be loaded, such as a
+     *  directory pathname, a JAR file pathname, or a ZIP file pathname
+     *
+     * @exception IllegalArgumentException if the specified repository is
+     *  invalid or does not exist
+     */
+    public void addRepository(String repository) {
+
+        // Ignore any of the standard repositories, as they are set up using
+        // either addJar or addRepository
+        if (repository.startsWith("/WEB-INF/lib")
+            || repository.startsWith("/WEB-INF/classes"))
+            return;
+
+        // Add this repository to our underlying class loader
+        try {
+            URL url = new URL(repository);
+            super.addURL(url);
+            hasExternalRepositories = true;
+            repositoryURLs = null;
+        } catch (MalformedURLException e) {
+            IllegalArgumentException iae = new IllegalArgumentException
+                ("Invalid repository: " + repository); 
+            jdkCompat.chainException(iae, e);
+            throw iae;
+        }
+
+    }
+
+
+    /**
+     * Add a new repository to the set of places this ClassLoader can look for
+     * classes to be loaded.
+     *
+     * @param repository Name of a source of classes to be loaded, such as a
+     *  directory pathname, a JAR file pathname, or a ZIP file pathname
+     *
+     * @exception IllegalArgumentException if the specified repository is
+     *  invalid or does not exist
+     */
+    synchronized void addRepository(String repository, File file) {
+
+        // Note : There should be only one (of course), but I think we should
+        // keep this a bit generic
+
+        if (repository == null)
+            return;
+
+        if (log.isDebugEnabled())
+            log.debug("addRepository(" + repository + ")");
+
+        int i;
+
+        // Add this repository to our internal list
+        String[] result = new String[repositories.length + 1];
+        for (i = 0; i < repositories.length; i++) {
+            result[i] = repositories[i];
+        }
+        result[repositories.length] = repository;
+        repositories = result;
+
+        // Add the file to the list
+        File[] result2 = new File[files.length + 1];
+        for (i = 0; i < files.length; i++) {
+            result2[i] = files[i];
+        }
+        result2[files.length] = file;
+        files = result2;
+
+    }
+
+
+    synchronized void addJar(String jar, JarFile jarFile, File file)
+        throws IOException {
+
+        if (jar == null)
+            return;
+        if (jarFile == null)
+            return;
+        if (file == null)
+            return;
+
+        if (log.isDebugEnabled())
+            log.debug("addJar(" + jar + ")");
+
+        int i;
+
+        if ((jarPath != null) && (jar.startsWith(jarPath))) {
+
+            String jarName = jar.substring(jarPath.length());
+            while (jarName.startsWith("/"))
+                jarName = jarName.substring(1);
+
+            String[] result = new String[jarNames.length + 1];
+            for (i = 0; i < jarNames.length; i++) {
+                result[i] = jarNames[i];
+            }
+            result[jarNames.length] = jarName;
+            jarNames = result;
+
+        }
+
+        try {
+
+            // Register the JAR for tracking
+
+            long lastModified =
+                ((ResourceAttributes) resources.getAttributes(jar))
+                .getLastModified();
+
+            String[] result = new String[paths.length + 1];
+            for (i = 0; i < paths.length; i++) {
+                result[i] = paths[i];
+            }
+            result[paths.length] = jar;
+            paths = result;
+
+            long[] result3 = new long[lastModifiedDates.length + 1];
+            for (i = 0; i < lastModifiedDates.length; i++) {
+                result3[i] = lastModifiedDates[i];
+            }
+            result3[lastModifiedDates.length] = lastModified;
+            lastModifiedDates = result3;
+
+        } catch (NamingException e) {
+            // Ignore
+        }
+
+        // If the JAR currently contains invalid classes, don't actually use it
+        // for classloading
+        if (!validateJarFile(file))
+            return;
+
+        JarFile[] result2 = new JarFile[jarFiles.length + 1];
+        for (i = 0; i < jarFiles.length; i++) {
+            result2[i] = jarFiles[i];
+        }
+        result2[jarFiles.length] = jarFile;
+        jarFiles = result2;
+
+        // Add the file to the list
+        File[] result4 = new File[jarRealFiles.length + 1];
+        for (i = 0; i < jarRealFiles.length; i++) {
+            result4[i] = jarRealFiles[i];
+        }
+        result4[jarRealFiles.length] = file;
+        jarRealFiles = result4;
+    }
+
+
+    /**
+     * Return a String array of the current repositories for this class
+     * loader.  If there are no repositories, 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());
+
+    }
+
+
+    /**
+     * Have one or more classes or resources been modified so that a reload
+     * is appropriate?
+     */
+    public boolean modified() {
+
+        if (log.isDebugEnabled())
+            log.debug("modified()");
+
+        // Checking for modified loaded resources
+        int length = paths.length;
+
+        // A rare race condition can occur in the updates of the two arrays
+        // It's totally ok if the latest class added is not checked (it will
+        // be checked the next time
+        int length2 = lastModifiedDates.length;
+        if (length > length2)
+            length = length2;
+
+        for (int i = 0; i < length; i++) {
+            try {
+                long lastModified =
+                    ((ResourceAttributes) resources.getAttributes(paths[i]))
+                    .getLastModified();
+                if (lastModified != lastModifiedDates[i]) {
+                    if( log.isDebugEnabled() ) 
+                        log.debug("  Resource '" + paths[i]
+                                  + "' was modified; Date is now: "
+                                  + new java.util.Date(lastModified) + " Was: "
+                                  + new java.util.Date(lastModifiedDates[i]));
+                    return (true);
+                }
+            } catch (NamingException e) {
+                log.error("    Resource '" + paths[i] + "' is missing");
+                return (true);
+            }
+        }
+
+        length = jarNames.length;
+
+        // Check if JARs have been added or removed
+        if (getJarPath() != null) {
+
+            try {
+                NamingEnumeration enum_ = resources.listBindings(getJarPath());
+                int i = 0;
+                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"))
+                        continue;
+                    if (!name.equals(jarNames[i])) {
+                        // Missing JAR
+                        log.info("    Additional JARs have been added : '" 
+                                 + name + "'");
+                        return (true);
+                    }
+                    i++;
+                }
+                if (enum_.hasMoreElements()) {
+                    while (enum_.hasMoreElements()) {
+                        NameClassPair ncPair = 
+                            (NameClassPair) enum_.nextElement();
+                        String name = ncPair.getName();
+                        // Additional non-JAR files are allowed
+                        if (name.endsWith(".jar")) {
+                            // There was more JARs
+                            log.info("    Additional JARs have been added");
+                            return (true);
+                        }
+                    }
+                } else if (i < jarNames.length) {
+                    // There was less JARs
+                    log.info("    Additional JARs have been added");
+                    return (true);
+                }
+            } catch (NamingException e) {
+                if (log.isDebugEnabled())
+                    log.debug("    Failed tracking modifications of '"
+                        + getJarPath() + "'");
+            } catch (ClassCastException e) {
+                log.error("    Failed tracking modifications of '"
+                          + getJarPath() + "' : " + e.getMessage());
+            }
+
+        }
+
+        // No classes have been modified
+        return (false);
+
+    }
+
+
+    /**
+     * Render a String representation of this object.
+     */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer("WebappClassLoader\r\n");
+        sb.append("  delegate: ");
+        sb.append(delegate);
+        sb.append("\r\n");
+        sb.append("  repositories:\r\n");
+        if (repositories != null) {
+            for (int i = 0; i < repositories.length; i++) {
+                sb.append("    ");
+                sb.append(repositories[i]);
+                sb.append("\r\n");
+            }
+        }
+        if (this.parent != null) {
+            sb.append("----------> Parent Classloader:\r\n");
+            sb.append(this.parent.toString());
+            sb.append("\r\n");
+        }
+        return (sb.toString());
+
+    }
+
+
+    // ---------------------------------------------------- ClassLoader Methods
+
+
+     /**
+      * Add the specified URL to the classloader.
+      */
+     protected void addURL(URL url) {
+         super.addURL(url);
+         hasExternalRepositories = true;
+         repositoryURLs = null;
+     }
+
+
+    /**
+     * Find the specified class in our local repositories, if possible.  If
+     * not found, throw <code>ClassNotFoundException</code>.
+     *
+     * @param name Name of the class to be loaded
+     *
+     * @exception ClassNotFoundException if the class was not found
+     */
+    public Class findClass(String name) throws ClassNotFoundException {
+
+        if (log.isDebugEnabled())
+            log.debug("    findClass(" + name + ")");
+
+        // (1) Permission to define this class when using a SecurityManager
+        if (securityManager != null) {
+            int i = name.lastIndexOf('.');
+            if (i >= 0) {
+                try {
+                    if (log.isTraceEnabled())
+                        log.trace("      securityManager.checkPackageDefinition");
+                    securityManager.checkPackageDefinition(name.substring(0,i));
+                } catch (Exception se) {
+                    if (log.isTraceEnabled())
+                        log.trace("      -->Exception-->ClassNotFoundException", se);
+                    throw new ClassNotFoundException(name, se);
+                }
+            }
+        }
+
+        // Ask our superclass to locate this class, if possible
+        // (throws ClassNotFoundException if it is not found)
+        Class clazz = null;
+        try {
+            if (log.isTraceEnabled())
+                log.trace("      findClassInternal(" + name + ")");
+            try {
+                clazz = findClassInternal(name);
+            } catch(ClassNotFoundException cnfe) {
+                if (!hasExternalRepositories) {
+                    throw cnfe;
+                }
+            } catch(AccessControlException ace) {
+                throw new ClassNotFoundException(name, ace);
+            } catch (RuntimeException e) {
+                if (log.isTraceEnabled())
+                    log.trace("      -->RuntimeException Rethrown", e);
+                throw e;
+            }
+            if ((clazz == null) && hasExternalRepositories) {
+                try {
+                    clazz = super.findClass(name);
+                } catch(AccessControlException ace) {
+                    throw new ClassNotFoundException(name, ace);
+                } catch (RuntimeException e) {
+                    if (log.isTraceEnabled())
+                        log.trace("      -->RuntimeException Rethrown", e);
+                    throw e;
+                }
+            }
+            if (clazz == null) {
+                if (log.isDebugEnabled())
+                    log.debug("    --> Returning ClassNotFoundException");
+                throw new ClassNotFoundException(name);
+            }
+        } catch (ClassNotFoundException e) {
+            if (log.isTraceEnabled())
+                log.trace("    --> Passing on ClassNotFoundException");
+            throw e;
+        }
+
+        // Return the class we have located
+        if (log.isTraceEnabled())
+            log.debug("      Returning class " + clazz);
+        if ((log.isTraceEnabled()) && (clazz != null))
+            log.debug("      Loaded by " + clazz.getClassLoader());
+        return (clazz);
+
+    }
+
+
+    /**
+     * Find the specified resource in our local repository, and return a
+     * <code>URL</code> refering to it, or <code>null</code> if this resource
+     * cannot be found.
+     *
+     * @param name Name of the resource to be found
+     */
+    public URL findResource(final String name) {
+
+        if (log.isDebugEnabled())
+            log.debug("    findResource(" + name + ")");
+
+        URL url = null;
+
+        ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
+        if (entry == null) {
+            entry = findResourceInternal(name, name);
+        }
+        if (entry != null) {
+            url = entry.source;
+        }
+
+        if ((url == null) && hasExternalRepositories)
+            url = super.findResource(name);
+
+        if (log.isDebugEnabled()) {
+            if (url != null)
+                log.debug("    --> Returning '" + url.toString() + "'");
+            else
+                log.debug("    --> Resource not found, returning null");
+        }
+        return (url);
+
+    }
+
+
+    /**
+     * Return an enumeration of <code>URLs</code> representing all of the
+     * resources with the given name.  If no resources with this name are
+     * found, return an empty enumeration.
+     *
+     * @param name Name of the resources to be found
+     *
+     * @exception IOException if an input/output error occurs
+     */
+    public Enumeration findResources(String name) throws IOException {
+
+        if (log.isDebugEnabled())
+            log.debug("    findResources(" + name + ")");
+
+        Vector result = new Vector();
+
+        int jarFilesLength = jarFiles.length;
+        int repositoriesLength = repositories.length;
+
+        int i;
+
+        // Looking at the repositories
+        for (i = 0; i < repositoriesLength; i++) {
+            try {
+                String fullPath = repositories[i] + name;
+                resources.lookup(fullPath);
+                // Note : Not getting an exception here means the resource was
+                // found
+                try {
+                    result.addElement(getURI(new File(files[i], name)));
+                } catch (MalformedURLException e) {
+                    // Ignore
+                }
+            } catch (NamingException e) {
+            }
+        }
+
+        // Looking at the JAR files
+        synchronized (jarFiles) {
+            openJARs();
+            for (i = 0; i < jarFilesLength; i++) {
+                JarEntry jarEntry = jarFiles[i].getJarEntry(name);
+                if (jarEntry != null) {
+                    try {
+                        String jarFakeUrl = getURI(jarRealFiles[i]).toString();
+                        jarFakeUrl = "jar:" + jarFakeUrl + "!/" + name;
+                        result.addElement(new URL(jarFakeUrl));
+                    } catch (MalformedURLException e) {
+                        // Ignore
+                    }
+                }
+            }
+        }
+
+        // Adding the results of a call to the superclass
+        if (hasExternalRepositories) {
+
+            Enumeration otherResourcePaths = super.findResources(name);
+
+            while (otherResourcePaths.hasMoreElements()) {
+                result.addElement(otherResourcePaths.nextElement());
+            }
+
+        }
+
+        return result.elements();
+
+    }
+
+
+    /**
+     * Find the resource with the given name.  A resource is some data
+     * (images, audio, text, etc.) that can be accessed by class code in a
+     * way that is independent of the location of the code.  The name of a
+     * resource is a "/"-separated path name that identifies the resource.
+     * If the resource cannot be found, return <code>null</code>.
+     * <p>
+     * This method searches according to the following algorithm, returning
+     * as soon as it finds the appropriate URL.  If the resource cannot be
+     * found, returns <code>null</code>.
+     * <ul>
+     * <li>If the <code>delegate</code> property is set to <code>true</code>,
+     *     call the <code>getResource()</code> method of the parent class
+     *     loader, if any.</li>
+     * <li>Call <code>findResource()</code> to find this resource in our
+     *     locally defined repositories.</li>
+     * <li>Call the <code>getResource()</code> method of the parent class
+     *     loader, if any.</li>
+     * </ul>
+     *
+     * @param name Name of the resource to return a URL for
+     */
+    public URL getResource(String name) {
+
+        if (log.isDebugEnabled())
+            log.debug("getResource(" + name + ")");
+        URL url = null;
+
+        // (1) Delegate to parent if requested
+        if (delegate) {
+            if (log.isDebugEnabled())
+                log.debug("  Delegating to parent classloader " + parent);
+            ClassLoader loader = parent;
+            if (loader == null)
+                loader = system;
+            url = loader.getResource(name);
+            if (url != null) {
+                if (log.isDebugEnabled())
+                    log.debug("  --> Returning '" + url.toString() + "'");
+                return (url);
+            }
+        }
+
+        // (2) Search local repositories
+        url = findResource(name);
+        if (url != null) {
+            // Locating the repository for special handling in the case 
+            // of a JAR
+            ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
+            try {
+                String repository = entry.codeBase.toString();
+                if ((repository.endsWith(".jar")) 
+                    && (!(name.endsWith(".class")))) {
+                    // Copy binary content to the work directory if not present
+                    File resourceFile = new File(loaderDir, name);
+                    url = resourceFile.toURL();
+                }
+            } catch (Exception e) {
+                // Ignore
+            }
+            if (log.isDebugEnabled())
+                log.debug("  --> Returning '" + url.toString() + "'");
+            return (url);
+        }
+
+        // (3) Delegate to parent unconditionally if not already attempted
+        if( !delegate ) {
+            ClassLoader loader = parent;
+            if (loader == null)
+                loader = system;
+            url = loader.getResource(name);
+            if (url != null) {
+                if (log.isDebugEnabled())
+                    log.debug("  --> Returning '" + url.toString() + "'");
+                return (url);
+            }
+        }
+
+        // (4) Resource was not found
+        if (log.isDebugEnabled())
+            log.debug("  --> Resource not found, returning null");
+        return (null);
+
+    }
+
+
+    /**
+     * Find the resource with the given name, and return an input stream
+     * that can be used for reading it.  The search order is as described
+     * for <code>getResource()</code>, after checking to see if the resource
+     * data has been previously cached.  If the resource cannot be found,
+     * return <code>null</code>.
+     *
+     * @param name Name of the resource to return an input stream for
+     */
+    public InputStream getResourceAsStream(String name) {
+
+        if (log.isDebugEnabled())
+            log.debug("getResourceAsStream(" + name + ")");
+        InputStream stream = null;
+
+        // (0) Check for a cached copy of this resource
+        stream = findLoadedResource(name);
+        if (stream != null) {
+            if (log.isDebugEnabled())
+                log.debug("  --> Returning stream from cache");
+            return (stream);
+        }
+
+        // (1) Delegate to parent if requested
+        if (delegate) {
+            if (log.isDebugEnabled())
+                log.debug("  Delegating to parent classloader " + parent);
+            ClassLoader loader = parent;
+            if (loader == null)
+                loader = system;
+            stream = loader.getResourceAsStream(name);
+            if (stream != null) {
+                // FIXME - cache???
+                if (log.isDebugEnabled())
+                    log.debug("  --> Returning stream from parent");
+                return (stream);
+            }
+        }
+
+        // (2) Search local repositories
+        if (log.isDebugEnabled())
+            log.debug("  Searching local repositories");
+        URL url = findResource(name);
+        if (url != null) {
+            // FIXME - cache???
+            if (log.isDebugEnabled())
+                log.debug("  --> Returning stream from local");
+            stream = findLoadedResource(name);
+            try {
+                if (hasExternalRepositories && (stream == null))
+                    stream = url.openStream();
+            } catch (IOException e) {
+                ; // Ignore
+            }
+            if (stream != null)
+                return (stream);
+        }
+
+        // (3) Delegate to parent unconditionally
+        if (!delegate) {
+            if (log.isDebugEnabled())
+                log.debug("  Delegating to parent classloader unconditionally " + parent);
+            ClassLoader loader = parent;
+            if (loader == null)
+                loader = system;
+            stream = loader.getResourceAsStream(name);
+            if (stream != null) {
+                // FIXME - cache???
+                if (log.isDebugEnabled())
+                    log.debug("  --> Returning stream from parent");
+                return (stream);
+            }
+        }
+
+        // (4) Resource was not found
+        if (log.isDebugEnabled())
+            log.debug("  --> Resource not found, returning null");
+        return (null);
+
+    }
+
+
+    /**
+     * Load the class with the specified name.  This method searches for
+     * classes in the same manner as <code>loadClass(String, boolean)</code>
+     * with <code>false</code> as the second argument.
+     *
+     * @param name Name of the class to be loaded
+     *
+     * @exception ClassNotFoundException if the class was not found
+     */
+    public Class loadClass(String name) throws ClassNotFoundException {
+
+        return (loadClass(name, false));
+
+    }
+
+
+    /**
+     * Load the class with the specified name, searching using the following
+     * algorithm until it finds and returns the class.  If the class cannot
+     * be found, returns <code>ClassNotFoundException</code>.
+     * <ul>
+     * <li>Call <code>findLoadedClass(String)</code> to check if the
+     *     class has already been loaded.  If it has, the same
+     *     <code>Class</code> object is returned.</li>
+     * <li>If the <code>delegate</code> property is set to <code>true</code>,
+     *     call the <code>loadClass()</code> method of the parent class
+     *     loader, if any.</li>
+     * <li>Call <code>findClass()</code> to find this class in our locally
+     *     defined repositories.</li>
+     * <li>Call the <code>loadClass()</code> method of our parent
+     *     class loader, if any.</li>
+     * </ul>
+     * If the class was found using the above steps, and the
+     * <code>resolve</code> flag is <code>true</code>, this method will then
+     * call <code>resolveClass(Class)</code> on the resulting Class object.
+     *
+     * @param name Name of the class to be loaded
+     * @param resolve If <code>true</code> then resolve the class
+     *
+     * @exception ClassNotFoundException if the class was not found
+     */
+    public Class loadClass(String name, boolean resolve)
+        throws ClassNotFoundException {
+
+        if (log.isDebugEnabled())
+            log.debug("loadClass(" + name + ", " + resolve + ")");
+        Class clazz = null;
+
+        // Don't load classes if class loader is stopped
+        if (!started) {
+            log.info(sm.getString("webappClassLoader.stopped"));
+            throw new ThreadDeath();
+        }
+
+        // (0) Check our previously loaded local class cache
+        clazz = findLoadedClass0(name);
+        if (clazz != null) {
+            if (log.isDebugEnabled())
+                log.debug("  Returning class from cache");
+            if (resolve)
+                resolveClass(clazz);
+            return (clazz);
+        }
+
+        // (0.1) Check our previously loaded class cache
+        clazz = findLoadedClass(name);
+        if (clazz != null) {
+            if (log.isDebugEnabled())
+                log.debug("  Returning class from cache");
+            if (resolve)
+                resolveClass(clazz);
+            return (clazz);
+        }
+
+        // (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);
+             clazz = Class.forName(name, false, null);
+             if (clazz != null) {
+                 if (resolve)
+                     resolveClass(clazz);
+                 return (clazz);
+             }
+        } catch (ClassNotFoundException e) {
+            // Ignore
+        }
+
+        // (0.5) Permission to access this class when using a SecurityManager
+        if (securityManager != null) {
+            int i = name.lastIndexOf('.');
+            if (i >= 0) {
+                try {
+                    securityManager.checkPackageAccess(name.substring(0,i));
+                } catch (SecurityException se) {
+                    String error = "Security Violation, attempt to use " +
+                        "Restricted Class: " + name;
+                    log.info(error, se);
+                    throw new ClassNotFoundException(error, se);
+                }
+            }
+        }
+
+        boolean delegateLoad = delegate || filter(name);
+
+        // (1) Delegate to our parent if requested
+        if (delegateLoad) {
+            if (log.isDebugEnabled())
+                log.debug("  Delegating to parent classloader1 " + parent);
+            ClassLoader loader = parent;
+            if (loader == null)
+                loader = system;
+            try {
+                clazz = loader.loadClass(name);
+                if (clazz != null) {
+                    if (log.isDebugEnabled())
+                        log.debug("  Loading class from parent");
+                    if (resolve)
+                        resolveClass(clazz);
+                    return (clazz);
+                }
+            } catch (ClassNotFoundException e) {
+                ;
+            }
+        }
+
+        // (2) Search local repositories
+        if (log.isDebugEnabled())
+            log.debug("  Searching local repositories");
+        try {
+            clazz = findClass(name);
+            if (clazz != null) {
+                if (log.isDebugEnabled())
+                    log.debug("  Loading class from local repository");
+                if (resolve)
+                    resolveClass(clazz);
+                return (clazz);
+            }
+        } catch (ClassNotFoundException e) {
+            ;
+        }
+
+        // (3) Delegate to parent unconditionally
+        if (!delegateLoad) {
+            if (log.isDebugEnabled())
+                log.debug("  Delegating to parent classloader at end: " + parent);
+            ClassLoader loader = parent;
+            if (loader == null)
+                loader = system;
+            try {
+                clazz = loader.loadClass(name);
+                if (clazz != null) {
+                    if (log.isDebugEnabled())
+                        log.debug("  Loading class from parent");
+                    if (resolve)
+                        resolveClass(clazz);
+                    return (clazz);
+                }
+            } catch (ClassNotFoundException e) {
+                ;
+            }
+        }
+
+        throw new ClassNotFoundException(name);
+    }
+
+
+    /**
+     * Get the Permissions for a CodeSource.  If this instance
+     * of WebappClassLoader is for a web application context,
+     * add read FilePermission or JndiPermissions for the base
+     * directory (if unpacked),
+     * the context URL, and jar file resources.
+     *
+     * @param codeSource where the code was loaded from
+     * @return PermissionCollection for CodeSource
+     */
+    protected PermissionCollection getPermissions(CodeSource codeSource) {
+
+        String codeUrl = codeSource.getLocation().toString();
+        PermissionCollection pc;
+        if ((pc = (PermissionCollection)loaderPC.get(codeUrl)) == null) {
+            pc = super.getPermissions(codeSource);
+            if (pc != null) {
+                Iterator perms = permissionList.iterator();
+                while (perms.hasNext()) {
+                    Permission p = (Permission)perms.next();
+                    pc.add(p);
+                }
+                loaderPC.put(codeUrl,pc);
+            }
+        }
+        return (pc);
+
+    }
+
+
+    /**
+     * Returns the search path of URLs for loading classes and resources.
+     * This includes the original list of URLs specified to the constructor,
+     * along with any URLs subsequently appended by the addURL() method.
+     * @return the search path of URLs for loading classes and resources.
+     */
+    public URL[] getURLs() {
+
+        if (repositoryURLs != null) {
+            return repositoryURLs;
+        }
+
+        URL[] external = super.getURLs();
+
+        int filesLength = files.length;
+        int jarFilesLength = jarRealFiles.length;
+        int length = filesLength + jarFilesLength + external.length;
+        int i;
+
+        try {
+
+            URL[] urls = new URL[length];
+            for (i = 0; i < length; i++) {
+                if (i < filesLength) {
+                    urls[i] = getURL(files[i]);
+                } else if (i < filesLength + jarFilesLength) {
+                    urls[i] = getURL(jarRealFiles[i - filesLength]);
+                } else {
+                    urls[i] = external[i - filesLength - jarFilesLength];
+                }
+            }
+
+            repositoryURLs = urls;
+
+        } catch (MalformedURLException e) {
+            repositoryURLs = new URL[0];
+        }
+
+        return repositoryURLs;
+
+    }
+
+
+    // ------------------------------------------------------ Lifecycle Methods
+
+
+    /**
+     * Add a lifecycle event listener to this component.
+     *
+     * @param listener The listener to add
+     */
+    public void addLifecycleListener(LifecycleListener 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 new LifecycleListener[0];
+    }
+
+
+    /**
+     * Remove a lifecycle event listener from this component.
+     *
+     * @param listener The listener to remove
+     */
+    public void removeLifecycleListener(LifecycleListener listener) {
+    }
+
+
+    /**
+     * Start the class loader.
+     *
+     * @exception LifecycleException if a lifecycle error occurs
+     */
+    public void start() throws LifecycleException {
+
+        started = true;
+
+    }
+
+
+    /**
+     * Stop the class loader.
+     *
+     * @exception LifecycleException if a lifecycle error occurs
+     */
+    public void stop() throws LifecycleException {
+
+        started = false;
+
+        int length = files.length;
+        for (int i = 0; i < length; i++) {
+            files[i] = null;
+        }
+
+        length = jarFiles.length;
+        for (int i = 0; i < length; i++) {
+            try {
+                if (jarFiles[i] != null) {
+                    jarFiles[i].close();
+                }
+            } catch (IOException e) {
+                // Ignore
+            }
+            jarFiles[i] = null;
+        }
+
+        notFoundResources.clear();
+        resourceEntries.clear();
+        resources = null;
+        repositories = null;
+        repositoryURLs = null;
+        files = null;
+        jarFiles = null;
+        jarRealFiles = null;
+        jarPath = null;
+        jarNames = null;
+        lastModifiedDates = null;
+        paths = null;
+        hasExternalRepositories = false;
+        parent = null;
+
+        permissionList.clear();
+        loaderPC.clear();
+
+        if (loaderDir != null) {
+            deleteDir(loaderDir);
+        }
+
+        org.apache.commons.logging.LogFactory.release(this);
+
+    }
+
+
+    /**
+     * Used to periodically signal to the classloader to release 
+     * JAR resources.
+     */
+    public void closeJARs(boolean force) {
+        if (jarFiles.length > 0) {
+            try {
+                synchronized (jarFiles) {
+                    if (force || (System.currentTimeMillis() 
+                                  > (lastJarAccessed + 90000))) {
+                        for (int i = 0; i < jarFiles.length; i++) {
+                            if (jarFiles[i] != null) {
+                                jarFiles[i].close();
+                                jarFiles[i] = null;
+                            }
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                log("Failed to close JAR", e);
+            }
+        }
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Used to periodically signal to the classloader to release JAR resources.
+     */
+    protected void openJARs() {
+        if (started && (jarFiles.length > 0)) {
+            lastJarAccessed = System.currentTimeMillis();
+            if (jarFiles[0] == null) {
+                try {
+                    for (int i = 0; i < jarFiles.length; i++) {
+                        jarFiles[i] = new JarFile(jarRealFiles[i]);
+                    }
+                } catch (IOException e) {
+                    log("Failed to open JAR", e);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Find specified class in local repositories.
+     *
+     * @return the loaded class, or null if the class isn't found
+     */
+    protected Class findClassInternal(String name)
+        throws ClassNotFoundException {
+
+        if (!validate(name))
+            throw new ClassNotFoundException(name);
+
+        String tempPath = name.replace('.', '/');
+        String classPath = tempPath + ".class";
+
+        ResourceEntry entry = null;
+
+        entry = findResourceInternal(name, classPath);
+
+        if ((entry == null) || (entry.binaryContent == null))
+            throw new ClassNotFoundException(name);
+
+        Class clazz = entry.loadedClass;
+        if (clazz != null)
+            return clazz;
+
+        // Looking up the package
+        String packageName = null;
+        int pos = name.lastIndexOf('.');
+        if (pos != -1)
+            packageName = name.substring(0, pos);
+
+        Package pkg = null;
+
+        if (packageName != null) {
+
+            pkg = getPackage(packageName);
+
+            // Define the package (if null)
+            if (pkg == null) {
+                if (entry.manifest == null) {
+                    definePackage(packageName, null, null, null, null, null,
+                                  null, null);
+                } else {
+                    definePackage(packageName, entry.manifest, entry.codeBase);
+                }
+            }
+
+        }
+
+        // Create the code source object
+        CodeSource codeSource =
+            new CodeSource(entry.codeBase, entry.certificates);
+
+        if (securityManager != null) {
+
+            // Checking sealing
+            if (pkg != null) {
+                boolean sealCheck = true;
+                if (pkg.isSealed()) {
+                    sealCheck = pkg.isSealed(entry.codeBase);
+                } else {
+                    sealCheck = (entry.manifest == null)
+                        || !isPackageSealed(packageName, entry.manifest);
+                }
+                if (!sealCheck)
+                    throw new SecurityException
+                        ("Sealing violation loading " + name + " : Package "
+                         + packageName + " is sealed.");
+            }
+
+        }
+
+        if (entry.loadedClass == null) {
+            synchronized (this) {
+                if (entry.loadedClass == null) {
+                    clazz = defineClass(name, entry.binaryContent, 0,
+                                        entry.binaryContent.length, 
+                                        codeSource);
+                    entry.loadedClass = clazz;
+                    entry.binaryContent = null;
+                    entry.source = null;
+                    entry.codeBase = null;
+                    entry.manifest = null;
+                    entry.certificates = null;
+                } else {
+                    clazz = entry.loadedClass;
+                }
+            }
+        } else {
+            clazz = entry.loadedClass;
+        }
+
+        return clazz;
+
+    }
+
+    /**
+     * Find specified resource in local repositories. This block
+     * will execute under an AccessControl.doPrivilege block.
+     *
+     * @return the loaded resource, or null if the resource isn't found
+     */
+    private ResourceEntry findResourceInternal(File file, String path){
+        ResourceEntry entry = new ResourceEntry();
+        try {
+            entry.source = getURI(new File(file, path));
+            entry.codeBase = getURL(new File(file, path));
+        } catch (MalformedURLException e) {
+            return null;
+        }   
+        return entry;
+    }
+    
+
+    /**
+     * Find specified resource in local repositories.
+     *
+     * @return the loaded resource, or null if the resource isn't found
+     */
+    protected ResourceEntry findResourceInternal(String name, String path) {
+
+        if (!started) {
+            log.info(sm.getString("webappClassLoader.stopped"));
+            return null;
+        }
+
+        if ((name == null) || (path == null))
+            return null;
+
+        ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
+        if (entry != null)
+            return entry;
+
+        int contentLength = -1;
+        InputStream binaryStream = null;
+
+        int jarFilesLength = jarFiles.length;
+        int repositoriesLength = repositories.length;
+
+        int i;
+
+        Resource resource = null;
+
+        for (i = 0; (entry == null) && (i < repositoriesLength); i++) {
+            try {
+
+                String fullPath = repositories[i] + path;
+
+                Object lookupResult = resources.lookup(fullPath);
+                if (lookupResult instanceof Resource) {
+                    resource = (Resource) lookupResult;
+                }
+
+                // Note : Not getting an exception here means the resource was
+                // found
+                 if (securityManager != null) {
+                    PrivilegedAction dp =
+                        new PrivilegedFindResource(files[i], path);
+                    entry = (ResourceEntry)AccessController.doPrivileged(dp);
+                 } else {
+                    entry = findResourceInternal(files[i], path);
+                 }
+
+                ResourceAttributes attributes =
+                    (ResourceAttributes) resources.getAttributes(fullPath);
+                contentLength = (int) attributes.getContentLength();
+                entry.lastModified = attributes.getLastModified();
+
+                if (resource != null) {
+
+                    try {
+                        binaryStream = resource.streamContent();
+                    } catch (IOException e) {
+                        return null;
+                    }
+
+                    // Register the full path for modification checking
+                    // Note: Only syncing on a 'constant' object is needed
+                    synchronized (allPermission) {
+
+                        int j;
+
+                        long[] result2 = 
+                            new long[lastModifiedDates.length + 1];
+                        for (j = 0; j < lastModifiedDates.length; j++) {
+                            result2[j] = lastModifiedDates[j];
+                        }
+                        result2[lastModifiedDates.length] = entry.lastModified;
+                        lastModifiedDates = result2;
+
+                        String[] result = new String[paths.length + 1];
+                        for (j = 0; j < paths.length; j++) {
+                            result[j] = paths[j];
+                        }
+                        result[paths.length] = fullPath;
+                        paths = result;
+
+                    }
+
+                }
+
+            } catch (NamingException e) {
+            }
+        }
+
+        if ((entry == null) && (notFoundResources.containsKey(name)))
+            return null;
+
+        JarEntry jarEntry = null;
+
+        synchronized (jarFiles) {
+
+            openJARs();
+            for (i = 0; (entry == null) && (i < jarFilesLength); i++) {
+
+                jarEntry = jarFiles[i].getJarEntry(path);
+
+                if (jarEntry != null) {
+
+                    entry = new ResourceEntry();
+                    try {
+                        entry.codeBase = getURL(jarRealFiles[i]);
+                        String jarFakeUrl = getURI(jarRealFiles[i]).toString();
+                        jarFakeUrl = "jar:" + jarFakeUrl + "!/" + path;
+                        entry.source = new URL(jarFakeUrl);
+                        entry.lastModified = jarRealFiles[i].lastModified();
+                    } catch (MalformedURLException e) {
+                        return null;
+                    }
+                    contentLength = (int) jarEntry.getSize();
+                    try {
+                        entry.manifest = jarFiles[i].getManifest();
+                        binaryStream = jarFiles[i].getInputStream(jarEntry);
+                    } catch (IOException e) {
+                        return null;
+                    }
+
+                    // Extract resources contained in JAR to the workdir
+                    if (!(path.endsWith(".class"))) {
+                        byte[] buf = new byte[1024];
+                        File resourceFile = new File
+                            (loaderDir, jarEntry.getName());
+                        if (!resourceFile.exists()) {
+                            Enumeration entries = jarFiles[i].entries();
+                            while (entries.hasMoreElements()) {
+                                JarEntry jarEntry2 = 
+                                    (JarEntry) entries.nextElement();
+                                if (!(jarEntry2.isDirectory()) 
+                                    && (!jarEntry2.getName().endsWith
+                                        (".class"))) {
+                                    resourceFile = new File
+                                        (loaderDir, jarEntry2.getName());
+                                    // No need to check mkdirs result because an
+                                    // IOException will occur anyway
+                                    resourceFile.getParentFile().mkdirs();
+                                    FileOutputStream os = null;
+                                    InputStream is = null;
+                                    try {
+                                        is = jarFiles[i].getInputStream
+                                            (jarEntry2);
+                                        os = new FileOutputStream
+                                            (resourceFile);
+                                        while (true) {
+                                            int n = is.read(buf);
+                                            if (n <= 0) {
+                                                break;
+                                            }
+                                            os.write(buf, 0, n);
+                                        }
+                                    } catch (IOException e) {
+                                        // Ignore
+                                    } finally {
+                                        try {
+                                            if (is != null) {
+                                                is.close();
+                                            }
+                                        } catch (IOException e) {
+                                        }
+                                        try {
+                                            if (os != null) {
+                                                os.close();
+                                            }
+                                        } catch (IOException e) {
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                }
+
+            }
+
+            if (entry == null) {
+                synchronized (notFoundResources) {
+                    notFoundResources.put(name, name);
+                }
+                return null;
+            }
+
+            if (binaryStream != null) {
+
+                byte[] binaryContent = new byte[contentLength];
+
+                try {
+                    int pos = 0;
+
+                    while (true) {
+                        int n = binaryStream.read(binaryContent, pos,
+                                                  binaryContent.length - pos);
+                        if (n <= 0)
+                            break;
+                        pos += n;
+                    }
+                    binaryStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    return null;
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return null;
+                }
+
+                entry.binaryContent = binaryContent;
+
+                // The certificates are only available after the JarEntry 
+                // associated input stream has been fully read
+                if (jarEntry != null) {
+                    entry.certificates = jarEntry.getCertificates();
+                }
+
+            }
+
+        }
+
+        // Add the entry in the local resource repository
+        synchronized (resourceEntries) {
+            // Ensures that all the threads which may be in a race to load
+            // a particular class all end up with the same ResourceEntry
+            // instance
+            ResourceEntry entry2 = (ResourceEntry) resourceEntries.get(name);
+            if (entry2 == null) {
+                resourceEntries.put(name, entry);
+            } else {
+                entry = entry2;
+            }
+        }
+
+        return entry;
+
+    }
+
+
+    /**
+     * Returns true if the specified package name is sealed according to the
+     * given manifest.
+     */
+    protected boolean isPackageSealed(String name, Manifest man) {
+
+        String path = name + "/";
+        Attributes attr = man.getAttributes(path);
+        String sealed = null;
+        if (attr != null) {
+            sealed = attr.getValue(Name.SEALED);
+        }
+        if (sealed == null) {
+            if ((attr = man.getMainAttributes()) != null) {
+                sealed = attr.getValue(Name.SEALED);
+            }
+        }
+        return "true".equalsIgnoreCase(sealed);
+
+    }
+
+
+    /**
+     * Finds the resource with the given name if it has previously been
+     * loaded and cached by this class loader, and return an input stream
+     * to the resource data.  If this resource has not been cached, return
+     * <code>null</code>.
+     *
+     * @param name Name of the resource to return
+     */
+    protected InputStream findLoadedResource(String name) {
+
+        ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
+        if (entry != null) {
+            if (entry.binaryContent != null)
+                return new ByteArrayInputStream(entry.binaryContent);
+        }
+        return (null);
+
+    }
+
+
+    /**
+     * Finds the class with the given name if it has previously been
+     * loaded and cached by this class loader, and return the Class object.
+     * If this class has not been cached, return <code>null</code>.
+     *
+     * @param name Name of the resource to return
+     */
+    protected Class findLoadedClass0(String name) {
+
+        ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
+        if (entry != null) {
+            return entry.loadedClass;
+        }
+        return (null);  // FIXME - findLoadedResource()
+
+    }
+
+
+    /**
+     * Refresh the system policy file, to pick up eventual changes.
+     */
+    protected void refreshPolicy() {
+
+        try {
+            // The policy file may have been modified to adjust 
+            // permissions, so we're reloading it when loading or 
+            // reloading a Context
+            Policy policy = Policy.getPolicy();
+            policy.refresh();
+        } catch (AccessControlException e) {
+            // Some policy files may restrict this, even for the core,
+            // so this exception is ignored
+        }
+
+    }
+
+
+    /**
+     * Filter classes.
+     * 
+     * @param name class name
+     * @return true if the class should be filtered
+     */
+    protected boolean filter(String name) {
+
+        if (name == null)
+            return false;
+
+        // Looking up the package
+        String packageName = null;
+        int pos = name.lastIndexOf('.');
+        if (pos != -1)
+            packageName = name.substring(0, pos);
+        else
+            return false;
+
+        for (int i = 0; i < packageTriggers.length; i++) {
+            if (packageName.startsWith(packageTriggers[i]))
+                return true;
+        }
+
+        return false;
+
+    }
+
+
+    /**
+     * Validate a classname. As per SRV.9.7.2, we must restict loading of 
+     * classes from J2SE (java.*) and classes of the servlet API 
+     * (javax.servlet.*). That should enhance robustness and prevent a number
+     * of user error (where an older version of servlet.jar would be present
+     * in /WEB-INF/lib).
+     * 
+     * @param name class name
+     * @return true if the name is valid
+     */
+    protected boolean validate(String name) {
+
+        if (name == null)
+            return false;
+        if (name.startsWith("java."))
+            return false;
+
+        return true;
+
+    }
+
+
+    /**
+     * Check the specified JAR file, and return <code>true</code> if it does
+     * not contain any of the trigger classes.
+     *
+     * @param jarfile The JAR file to be checked
+     *
+     * @exception IOException if an input/output error occurs
+     */
+    private boolean validateJarFile(File jarfile)
+        throws IOException {
+
+        if (triggers == null)
+            return (true);
+        JarFile jarFile = new JarFile(jarfile);
+        for (int i = 0; i < triggers.length; i++) {
+            Class clazz = null;
+            try {
+                if (parent != null) {
+                    clazz = parent.loadClass(triggers[i]);
+                } else {
+                    clazz = Class.forName(triggers[i]);
+                }
+            } catch (Throwable t) {
+                clazz = null;
+            }
+            if (clazz == null)
+                continue;
+            String name = triggers[i].replace('.', '/') + ".class";
+            if (log.isDebugEnabled())
+                log.debug(" Checking for " + name);
+            JarEntry jarEntry = jarFile.getJarEntry(name);
+            if (jarEntry != null) {
+                log.info("validateJarFile(" + jarfile + 
+                    ") - jar not loaded. See Servlet Spec 2.3, "
+                    + "section 9.7.2. Offending class: " + name);
+                jarFile.close();
+                return (false);
+            }
+        }
+        jarFile.close();
+        return (true);
+
+    }
+
+
+    /**
+     * Get URL.
+     */
+    protected URL getURL(File file)
+        throws MalformedURLException {
+
+        File realFile = file;
+        try {
+            realFile = realFile.getCanonicalFile();
+        } catch (IOException e) {
+            // Ignore
+        }
+        return realFile.toURL();
+
+    }
+
+
+    /**
+     * Get URL.
+     */
+    protected URL getURI(File file)
+        throws MalformedURLException {
+
+        return jdkCompat.getURI(file);
+
+    }
+
+
+    /**
+     * Delete the specified directory, including all of its contents and
+     * subdirectories recursively.
+     *
+     * @param dir File object representing the directory to be deleted
+     */
+    protected static void deleteDir(File dir) {
+
+        String files[] = dir.list();
+        if (files == null) {
+            files = new String[0];
+        }
+        for (int i = 0; i < files.length; i++) {
+            File file = new File(dir, files[i]);
+            if (file.isDirectory()) {
+                deleteDir(file);
+            } else {
+                file.delete();
+            }
+        }
+        dir.delete();
+
+    }
+
+
+    /**
+     * Log a debugging output message.
+     *
+     * @param message Message to be logged
+     */
+    private void log(String message) {
+
+        System.out.println("WebappClassLoader: " + message);
+
+    }
+
+
+    /**
+     * Log a debugging output message with an exception.
+     *
+     * @param message Message to be logged
+     * @param throwable Exception to be logged
+     */
+    private void log(String message, Throwable throwable) {
+
+        System.out.println("WebappClassLoader: " + message);
+        throwable.printStackTrace(System.out);
+
+    }
+
+}
diff --git a/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java b/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java
new file mode 100644
index 0000000..8955714
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/GWTCompilerTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.GWTCompiler.GWTCompilerOptionsImpl;
+import com.google.gwt.dev.jjs.JsOutputOption;
+
+import java.io.File;
+
+/**
+ * Test for deprecated {@link GWTShell}.
+ */
+@SuppressWarnings("deprecation")
+public class GWTCompilerTest extends ArgProcessorTestBase {
+
+  private final GWTCompiler.ArgProcessor argProcessor;
+  private final GWTCompilerOptionsImpl options = new GWTCompilerOptionsImpl();
+
+  public GWTCompilerTest() {
+    argProcessor = new GWTCompiler.ArgProcessor(options);
+  }
+
+  public void testAllValidArgs() {
+    assertProcessSuccess(argProcessor, "-logLevel", "DEBUG", "-style",
+        "PRETTY", "-ea", "-XdisableAggressiveOptimization", "-out", "myWww",
+        "-gen", "myGen", "c.g.g.h.H", "my.Module");
+
+    assertEquals(new File("myGen").getAbsoluteFile(),
+        options.getGenDir().getAbsoluteFile());
+    assertEquals(new File("myWww"), options.getOutDir());
+
+    assertEquals(TreeLogger.DEBUG, options.getLogLevel());
+    assertEquals(JsOutputOption.PRETTY, options.getOutput());
+    assertTrue(options.isEnableAssertions());
+    assertFalse(options.isAggressivelyOptimize());
+
+    assertEquals(2, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+    assertEquals("my.Module", options.getModuleNames().get(1));
+  }
+
+  public void testDefaultArgs() {
+    assertProcessSuccess(argProcessor, "c.g.g.h.H");
+
+    assertEquals(null, options.getGenDir());
+    assertEquals(new File("").getAbsoluteFile(),
+        options.getOutDir().getAbsoluteFile());
+
+    assertEquals(TreeLogger.INFO, options.getLogLevel());
+    assertEquals(JsOutputOption.OBFUSCATED, options.getOutput());
+    assertFalse(options.isEnableAssertions());
+    assertTrue(options.isAggressivelyOptimize());
+
+    assertEquals(1, options.getModuleNames().size());
+    assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
+  }
+
+  public void testForbiddenArgs() {
+    assertProcessFailure(argProcessor, "-localWorkers", "2");
+    assertProcessFailure(argProcessor, "-extra", "extra");
+    assertProcessFailure(argProcessor, "-war", "war");
+    assertProcessFailure(argProcessor, "-work", "work");
+  }
+}
diff --git a/dev/core/test/com/google/gwt/dev/GWTShellTest.java b/dev/core/test/com/google/gwt/dev/GWTShellTest.java
new file mode 100644
index 0000000..557189e
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/GWTShellTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.GWTShell.ShellOptionsImpl;
+import com.google.gwt.dev.HostedModeTest.MySCL;
+import com.google.gwt.dev.jjs.JsOutputOption;
+import com.google.gwt.dev.shell.BrowserWidgetHostChecker;
+
+import java.io.File;
+
+/**
+ * Test for deprecated {@link GWTShell}.
+ */
+@SuppressWarnings("deprecation")
+public class GWTShellTest extends ArgProcessorTestBase {
+
+  private final GWTShell.ArgProcessor argProcessor;
+  private final ShellOptionsImpl options = new ShellOptionsImpl();
+
+  public GWTShellTest() {
+    argProcessor = new GWTShell.ArgProcessor(options, false, false);
+  }
+
+  public void testAllValidArgs() {
+    assertProcessSuccess(argProcessor, "-port", "8080", "-whitelist", "white",
+        "-blacklist", "black", "-logLevel", "DEBUG", "-noserver", "-out",
+        "myWww", "-gen", "myGen", "http://www.google.com/", "foo");
+
+    assertNotNull(BrowserWidgetHostChecker.matchWhitelisted("white"));
+    assertNotNull(BrowserWidgetHostChecker.matchBlacklisted("black"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40:88"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40:88/"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1.40:88/foo"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org:88"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org:88/"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org:88/foo"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org/"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://localhost.evildomain.org/foo"));
+    assertFalse(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://www.evildomain.org/foo?http://localhost"));
+    assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1"));
+    assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1:88"));
+    assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1:88/"));
+    assertTrue(BrowserWidgetHostChecker.isAlwaysWhitelisted("http://127.0.0.1:88/foo"));
+
+    assertEquals(new File("myGen").getAbsoluteFile(),
+        options.getGenDir().getAbsoluteFile());
+    assertEquals(new File("myWww"), options.getOutDir());
+
+    assertEquals(TreeLogger.DEBUG, options.getLogLevel());
+
+    assertEquals(8080, options.getPort());
+    assertTrue(options.isNoServer());
+    assertEquals(2, options.getStartupURLs().size());
+    assertEquals("http://www.google.com/", options.getStartupURLs().get(0));
+    assertEquals("foo", options.getStartupURLs().get(1));
+  }
+
+  public void testDefaultArgs() {
+    assertProcessSuccess(argProcessor);
+
+    assertEquals(null, options.getGenDir());
+    assertEquals(new File("").getAbsoluteFile(),
+        options.getOutDir().getAbsoluteFile());
+
+    assertEquals(TreeLogger.INFO, options.getLogLevel());
+    assertEquals(JsOutputOption.OBFUSCATED, options.getOutput());
+    assertFalse(options.isEnableAssertions());
+    assertTrue(options.isAggressivelyOptimize());
+
+    assertEquals(8888, options.getPort());
+    assertFalse(options.isNoServer());
+    assertEquals(0, options.getStartupURLs().size());
+  }
+
+  public void testForbiddenArgs() {
+    assertProcessFailure(argProcessor, "-localWorkers", "2");
+    assertProcessFailure(argProcessor, "-extra", "extra");
+    assertProcessFailure(argProcessor, "-war", "war");
+    assertProcessFailure(argProcessor, "-work", "work");
+    assertProcessFailure(argProcessor, "-server", MySCL.class.getName());
+  }
+}
diff --git a/eclipse/dev/.classpath b/eclipse/dev/.classpath
index 4b1f5b4..fa17a0d 100644
--- a/eclipse/dev/.classpath
+++ b/eclipse/dev/.classpath
@@ -12,16 +12,35 @@
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/ant-launcher-1.6.5.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/catalina-1.0.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/catalina-optional-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-beanutils-1.6.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-collections-3.1.jar" sourcepath="/GWT_TOOLS/lib/tomcat/commons-collections-3.1-src.zip"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-digester-1.5.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-el-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-logging-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/commons-modeler-1.1.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jakarta-regexp-1.3.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jasper-compiler-1.0.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jasper-runtime-1.0.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/jsp-api-2.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/mx4j-jmx-1.1.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-common-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-factory-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-java-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/naming-resources-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlet-api-2.5.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlet-api-2.4.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlets-common-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlets-default-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlets-invoker-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-coyote-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-http11-1.0.jar" sourcepath="/GWT_TOOLS/lib/tomcat/tomcat-http11-1.0.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-jk2-2.1.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/tomcat-util-5.1.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-core-js-2.9.jar" sourcepath="/GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-core-js-2.9-sources.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-2.9.jar" sourcepath="/GWT_TOOLS/lib/htmlunit/htmlunit-2.9/htmlunit-2.9-sources.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/protobuf/protobuf-2.2.0/protobuf-java-rebased-2.2.0.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/guava/guava-10.0.1/guava-10.0.1-rebased.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/jscomp/sourcemap-rebased.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/jscomp/r1649/compiler-rebased.jar"/>
-	<classpathentry kind="var" path="GWT_TOOLS/lib/apache/commons/commons-collections-3.2.1.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
