Migrating ApplicationCreator to WebAppCreator.

Still TODO: figure out a real solution for samples with eclipse in distro.


git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4443 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/ArgProcessorBase.java b/dev/core/src/com/google/gwt/dev/ArgProcessorBase.java
index 3f38920..641ae7a 100644
--- a/dev/core/src/com/google/gwt/dev/ArgProcessorBase.java
+++ b/dev/core/src/com/google/gwt/dev/ArgProcessorBase.java
@@ -20,7 +20,7 @@
 /**
  * Base class for new-style argument processors.
  */
-abstract class ArgProcessorBase extends ToolBase {
+public abstract class ArgProcessorBase extends ToolBase {
   /*
    * Overridden to make public.
    */
diff --git a/dev/core/src/com/google/gwt/dev/util/Util.java b/dev/core/src/com/google/gwt/dev/util/Util.java
index aabd864..c3c4a4f 100644
--- a/dev/core/src/com/google/gwt/dev/util/Util.java
+++ b/dev/core/src/com/google/gwt/dev/util/Util.java
@@ -673,6 +673,18 @@
     return null;
   }
 
+  /**
+   * @return null if the file could not be read
+   */
+  public static String readURLAsString(URL url) {
+    byte[] bytes = readURLAsBytes(url);
+    if (bytes != null) {
+      return toString(bytes, DEFAULT_ENCODING);
+    }
+
+    return null;
+  }
+
   public static byte[] readURLConnectionAsBytes(URLConnection connection) {
     // ENH: add a weak cache that has an additional check against the file date
     InputStream input = null;
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerModuleName.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerModuleName.java
index de2403a..0f29740 100644
--- a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerModuleName.java
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerModuleName.java
@@ -18,7 +18,7 @@
 import com.google.gwt.util.tools.ArgHandlerExtra;
 
 /**
- * Argument handler for module name, which has no option profix.
+ * Argument handler for one or more module names at the end of the command line.
  */
 public class ArgHandlerModuleName extends ArgHandlerExtra {
 
diff --git a/dev/core/src/com/google/gwt/util/tools/Utility.java b/dev/core/src/com/google/gwt/util/tools/Utility.java
index 03697bf..0f9957f 100644
--- a/dev/core/src/com/google/gwt/util/tools/Utility.java
+++ b/dev/core/src/com/google/gwt/util/tools/Utility.java
@@ -211,10 +211,7 @@
         throw new FileNotFoundException(partialPath);
       }
       ByteArrayOutputStream os = new ByteArrayOutputStream();
-      int ch;
-      while ((ch = in.read()) != -1) {
-        os.write(ch);
-      }
+      streamOut(in, os, 1024);
       return new String(os.toByteArray(), "UTF-8");
     } finally {
       close(in);
diff --git a/user/src/com/google/gwt/user/tools/.classpathsrc b/user/src/com/google/gwt/user/tools/.classpathsrc
index 7b82224..d2b73b6 100644
--- a/user/src/com/google/gwt/user/tools/.classpathsrc
+++ b/user/src/com/google/gwt/user/tools/.classpathsrc
@@ -4,5 +4,5 @@
    <classpathentry kind="lib" path="@gwtUserPath"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-   <classpathentry kind="output" path="war/WEB-INF/classes"/>@eclipseClassPathEntries
+   <classpathentry kind="output" path="war/WEB-INF/classes"/>
 </classpath>
diff --git a/user/src/com/google/gwt/user/tools/.projectsrc b/user/src/com/google/gwt/user/tools/.projectsrc
index 23afa59..2436f15 100644
--- a/user/src/com/google/gwt/user/tools/.projectsrc
+++ b/user/src/com/google/gwt/user/tools/.projectsrc
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <projectDescription>
-   <name>@projectName</name>
-   <comment>@projectName project</comment>
+   <name>@moduleShortName</name>
+   <comment>@moduleShortName project</comment>
    <projects/>
    <buildSpec>
        <buildCommand>
diff --git a/user/src/com/google/gwt/user/tools/App.launchsrc b/user/src/com/google/gwt/user/tools/App.launchsrc
index 227ac01..428e717 100644
--- a/user/src/com/google/gwt/user/tools/App.launchsrc
+++ b/user/src/com/google/gwt/user/tools/App.launchsrc
@@ -3,14 +3,13 @@
 <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="@shellClass"/>
 <listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;@projectName&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/@projectName/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
-<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento project=&quot;@projectName&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot; javaProject=&quot;@moduleShortName&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/@moduleShortName/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento project=&quot;@moduleShortName&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
 <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;runtimeClasspathEntry externalArchive=&quot;@gwtDevPath&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
-@eclipseExtraLaunchPaths
 </listAttribute>
 <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256M@vmargs"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-startupUrl&#10;@startupUrl @moduleName"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="@projectName"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="@moduleShortName"/>
 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
 </launchConfiguration>
diff --git a/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc b/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
index 9e344af..6a25968 100644
--- a/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
+++ b/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
@@ -15,7 +15,7 @@
 /**
  * Entry point classes define <code>onModuleLoad()</code>.
  */
-public class @className implements EntryPoint {
+public class @moduleShortName implements EntryPoint {
 
   /**
    * Create a remote service proxy to talk to the server-side Echo service.
diff --git a/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc b/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
index 2090fe7..47a42e3 100644
--- a/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
+++ b/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
@@ -12,18 +12,18 @@
     <!--                                                               -->
     <!-- Consider inlining CSS to reduce the number of requested files -->
     <!--                                                               -->
-    <link type="text/css" rel="stylesheet" href="@className.css">
+    <link type="text/css" rel="stylesheet" href="@moduleShortName.css">
     <!--                                           -->
     <!-- Any title is fine                         -->
     <!--                                           -->
-    <title>@className</title>
+    <title>@moduleShortName</title>
     
     <!--                                           -->
     <!-- This script loads your compiled module.   -->
     <!-- If you add any GWT meta tags, they must   -->
     <!-- be added before this line.                -->
     <!--                                           -->
-    <script type="text/javascript" language="javascript" src="@newModuleName/@newModuleName.nocache.js"></script>
+    <script type="text/javascript" language="javascript" src="@renameTo/@renameTo.nocache.js"></script>
   </head>
 
   <!--                                           -->
diff --git a/user/src/com/google/gwt/user/tools/ApplicationCreator.java b/user/src/com/google/gwt/user/tools/ApplicationCreator.java
index 90e1092..9097740 100644
--- a/user/src/com/google/gwt/user/tools/ApplicationCreator.java
+++ b/user/src/com/google/gwt/user/tools/ApplicationCreator.java
@@ -15,520 +15,15 @@
  */
 package com.google.gwt.user.tools;
 
-import com.google.gwt.dev.About;
-import com.google.gwt.dev.Compiler;
-import com.google.gwt.dev.HostedMode;
-import com.google.gwt.dev.cfg.ModuleDefLoader;
-import com.google.gwt.user.tools.util.ArgHandlerAddToClassPath;
-import com.google.gwt.user.tools.util.ArgHandlerEclipse;
-import com.google.gwt.user.tools.util.ArgHandlerIgnore;
-import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
-import com.google.gwt.user.tools.util.CreatorUtilities;
-import com.google.gwt.util.tools.ArgHandlerExtra;
-import com.google.gwt.util.tools.ArgHandlerOutDir;
-import com.google.gwt.util.tools.ArgHandlerString;
-import com.google.gwt.util.tools.ToolBase;
-import com.google.gwt.util.tools.Utility;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
 /**
- * Creates a GWT application skeleton.
+ * Legacy ApplicationCreator that will let users know that they should run
+ * {@link WebAppCreator} instead.
  */
-public final class ApplicationCreator extends ToolBase {
-
-  /*
-   * Arguments for the application creator.
-   */
-
-  /**
-   * Add an extra module injection into the top level module file.
-   */
-  protected class ArgHandlerAddModule extends ArgHandlerString {
-    private List<String> extraModuleList = new ArrayList<String>();
-
-    public List<String> getExtraModuleList() {
-      return extraModuleList;
-    }
-
-    @Override
-    public String getPurpose() {
-      return "Adds extra GWT modules to be inherited.";
-    }
-
-    @Override
-    public String getTag() {
-      return "-addModule";
-    }
-
-    @Override
-    public String[] getTagArgs() {
-      return new String[] {"module"};
-    }
-
-    @Override
-    public boolean setString(String str) {
-      // Parse out a comma separated list
-      StringTokenizer st = new StringTokenizer(str, ",");
-      while (st.hasMoreTokens()) {
-        String module = st.nextToken();
-
-        // Check className to see that it is a period separated string of words.
-        if (!module.matches("[\\w\\$]+(\\.[\\w\\$]+)+")) {
-          System.err.println("'" + module
-              + "' does not appear to be a valid fully-qualified module name");
-          return false;
-        }
-        extraModuleList.add(module);
-      }
-
-      return true;
-    }
-  }
-
-  /**
-   * Specify the top level class name of the application to create.
-   */
-  protected class ArgHandlerAppClass extends ArgHandlerExtra {
-
-    @Override
-    public boolean addExtraArg(String arg) {
-      if (fullClassName != null) {
-        System.err.println("Too many arguments");
-        return false;
-      }
-
-      // Check className for certain properties
-      if (!arg.matches("[\\w\\$]+(\\.[\\w\\$]+)+")) {
-        System.err.println("'" + arg
-            + "' does not appear to be a valid fully-qualified Java class name");
-        return false;
-      }
-
-      // Check out the class name.
-      if (arg.indexOf('$') != -1) {
-        System.err.println("'" + arg
-            + "': This version of the tool does not support nested classes");
-        return false;
-      }
-
-      String[] parts = arg.split("\\.");
-      if (parts.length < 2 || !parts[parts.length - 2].equals("client")) {
-        System.err.println("'"
-            + arg
-            + "': Please use 'client' as the final package, as in 'com.example.foo.client.MyApp'.\n"
-            + "It isn't technically necessary, but this tool enforces the best practice.");
-        return false;
-      }
-
-      fullClassName = arg;
-      return true;
-    }
-
-    @Override
-    public String getPurpose() {
-      return "The fully-qualified name of the application class to create";
-    }
-
-    @Override
-    public String[] getTagArgs() {
-      return new String[] {"className"};
-    }
-
-    @Override
-    public boolean isRequired() {
-      return true;
-    }
-  }
-
-  static class FileCreator {
-    private final File dir;
-    private final String sourceName;
-    private final String className;
-
-    FileCreator(File dir, String sourceName, String className) {
-      this.dir = dir;
-      this.sourceName = sourceName;
-      this.className = className;
-    }
-  }
-
-  private static final String PACKAGE_PATH;
-
-  static {
-    String path = ApplicationCreator.class.getName();
-    path = path.substring(0, path.lastIndexOf('.') + 1);
-    PACKAGE_PATH = path.replace('.', '/');
-  }
+public final class ApplicationCreator {
 
   public static void main(String[] args) {
-    ApplicationCreator creator = new ApplicationCreator();
-    if (creator.processArgs(args)) {
-      if (creator.run()) {
-        return;
-      }
-    }
+    System.err.println("This application no longer exists!");
+    System.err.println("Please see " + WebAppCreator.class.getName());
     System.exit(1);
   }
-
-  /**
-   * @param fullClassName Name of the fully-qualified Java class to create as an
-   *          Application.
-   * @param outDir Where to put the output files
-   * @param eclipse The name of a project to attach a .launch config to
-   * @param overwrite Overwrite an existing files if they exist.
-   * @param ignore Ignore existing files if they exist.
-   * @throws IOException
-   */
-  static void createApplication(String fullClassName, File outDir,
-      String eclipse, boolean overwrite, boolean ignore) throws IOException {
-    createApplication(fullClassName, outDir, eclipse, overwrite, ignore, null,
-        null);
-  }
-
-  /**
-   * @param fullClassName Name of the fully-qualified Java class to create as an
-   *          Application.
-   * @param outDir Where to put the output files
-   * @param eclipse The name of a project to attach a .launch config to
-   * @param overwrite Overwrite an existing files if they exist.
-   * @param ignore Ignore existing files if they exist.
-   * @param extraClassPaths A list of paths to append to the class path for
-   *          launch configs.
-   * @param extraModules A list of GWT modules to add 'inherits' tags for.
-   * @throws IOException
-   */
-  static void createApplication(String fullClassName, File outDir,
-      String eclipse, boolean overwrite, boolean ignore,
-      List<String> extraClassPaths, List<String> extraModules)
-      throws IOException {
-    createApplication(fullClassName, outDir, eclipse, overwrite, ignore,
-        extraClassPaths, extraModules, null);
-  }
-
-  /**
-   * @param fullClassName Name of the fully-qualified Java class to create as an
-   *          Application.
-   * @param outDir Where to put the output files
-   * @param eclipse The name of a project to attach a .launch config to
-   * @param overwrite Overwrite an existing files if they exist.
-   * @param ignore Ignore existing files if they exist.
-   * @param extraClassPaths A list of paths to append to the class path for
-   *          launch configs.
-   * @param extraModules A list of GWT modules to add 'inherits' tags for.
-   * @param newModuleName The new module name
-   * @throws IOException
-   */
-  static void createApplication(String fullClassName, File outDir,
-      String eclipse, boolean overwrite, boolean ignore,
-      List<String> extraClassPaths, List<String> extraModules,
-      String newModuleName) throws IOException {
-
-    // Figure out the installation directory
-
-    String installPath = Utility.getInstallPath();
-    String gwtUserPath = installPath + '/' + "gwt-user.jar";
-    String gwtDevPath = installPath + '/' + Utility.getDevJarName();
-    String gwtServletPath = installPath + '/' + "gwt-servlet.jar";
-
-    // Public builds generate a DTD reference.
-    String gwtModuleDtd = "";
-    if (!About.GWT_VERSION_NUM.endsWith(".999")
-        && !About.GWT_VERSION_NUM.startsWith("0.0")) {
-      gwtModuleDtd = "\n<!DOCTYPE module PUBLIC \"-//Google Inc.//DTD Google Web Toolkit "
-          + About.GWT_VERSION_NUM
-          + "//EN\" \"http://google-web-toolkit.googlecode.com/svn/tags/"
-          + About.GWT_VERSION_NUM + "/distro-source/core/src/gwt-module.dtd\">";
-    }
-
-    // Validate the arguments for extra class path entries and modules.
-    if (!CreatorUtilities.validatePathsAndModules(gwtUserPath, extraClassPaths,
-        extraModules)) {
-      return;
-    }
-    // Figure out what platform we're on
-    boolean isMacOsX = gwtDevPath.substring(gwtDevPath.lastIndexOf('/') + 1).indexOf(
-        "mac") >= 0;
-
-    // Check out the class and package names.
-    int pos = fullClassName.lastIndexOf('.');
-    String clientPackageName = fullClassName.substring(0, pos);
-    String className = fullClassName.substring(pos + 1);
-
-    // Compute module name and directories
-    pos = clientPackageName.lastIndexOf('.');
-    File basePackageDir;
-    String moduleName;
-    String serverPackageName = null;
-    File javaDir = Utility.getDirectory(outDir, "src", true);
-    File warDir = Utility.getDirectory(outDir, "war", true);
-    File webInfDir = Utility.getDirectory(warDir, "WEB-INF", true);
-    if (pos >= 0) {
-      String basePackage = clientPackageName.substring(0, pos);
-      moduleName = basePackage + "." + className;
-      serverPackageName = basePackage + ".server";
-      basePackage = basePackage.replace('.', '/');
-      basePackageDir = Utility.getDirectory(javaDir, basePackage, true);
-    } else {
-      moduleName = className;
-      basePackageDir = javaDir;
-      serverPackageName = "server";
-    }
-    File clientDir = Utility.getDirectory(basePackageDir, "client", true);
-    File serverDir = Utility.getDirectory(basePackageDir, "server", true);
-    String startupUrl = className + ".html";
-
-    // Create a map of replacements
-    //
-    Map<String, String> replacements = new HashMap<String, String>();
-    replacements.put("@className", className);
-    replacements.put("@moduleName", moduleName);
-    replacements.put("@clientPackage", clientPackageName);
-    replacements.put("@serverPackage", serverPackageName);
-    replacements.put("@gwtUserPath", gwtUserPath);
-    replacements.put("@gwtDevPath", gwtDevPath);
-    replacements.put("@gwtVersion", About.GWT_VERSION_NUM);
-    replacements.put("@gwtModuleDtd", gwtModuleDtd);
-    replacements.put("@shellClass", HostedMode.class.getName());
-    replacements.put("@compileClass", Compiler.class.getName());
-    replacements.put("@startupUrl", startupUrl);
-    replacements.put("@antVmargs", isMacOsX
-        ? "\n<jvmarg value=\"-XstartOnFirstThread\"/>" : "");
-    replacements.put("@vmargs", isMacOsX ? "&#10;-XstartOnFirstThread" : "");
-    replacements.put("@eclipseExtraLaunchPaths",
-        CreatorUtilities.createEclipseExtraLaunchPaths(extraClassPaths));
-    replacements.put("@extraModuleInherits",
-        createExtraModuleInherits(extraModules));
-    replacements.put("@extraClassPathsColon", CreatorUtilities.appendPaths(":",
-        extraClassPaths));
-    replacements.put("@extraClassPathsSemicolon", CreatorUtilities.appendPaths(
-        ";", extraClassPaths));
-    replacements.put("@newModuleName", (newModuleName != null) ? newModuleName
-        : moduleName);
-
-    {
-      // create the module xml file, skeleton html file, skeleton css file,
-      // web.xml file
-      FileCreator fileCreators[] = new FileCreator[] {
-          new FileCreator(basePackageDir, "Module.gwt.xml", className
-              + ModuleDefLoader.GWT_MODULE_XML_SUFFIX),
-          new FileCreator(warDir, "AppHtml.html", className + ".html"),
-          new FileCreator(warDir, "AppCss.css", className + ".css"),
-          new FileCreator(webInfDir, "web.xml", "web.xml"),};
-      for (FileCreator fileCreator : fileCreators) {
-        File file = Utility.createNormalFile(fileCreator.dir,
-            fileCreator.className, overwrite, ignore);
-        if (file != null) {
-          String out = Utility.getFileFromClassPath(PACKAGE_PATH
-              + fileCreator.sourceName + "src");
-          Utility.writeTemplateFile(file, out, replacements);
-        }
-      }
-    }
-
-    {
-      /*
-       * Create a skeleton Application: main client class, rpc stub for the
-       * client, async counterpart of the rpc stub, rpc implementation on the
-       * server.
-       */
-      FileCreator fileCreators[] = new FileCreator[] {
-          new FileCreator(clientDir, "AppClass", className),
-          new FileCreator(clientDir, "RpcClient", "EchoService"),
-          new FileCreator(clientDir, "RpcAsyncClient", "EchoServiceAsync"),
-          new FileCreator(serverDir, "RpcServer", "EchoServiceImpl"),};
-      for (FileCreator fileCreator : fileCreators) {
-        File javaClass = Utility.createNormalFile(fileCreator.dir,
-            fileCreator.className + ".java", overwrite, ignore);
-        if (javaClass != null) {
-          String out = Utility.getFileFromClassPath(PACKAGE_PATH
-              + fileCreator.sourceName + "Template.javasrc");
-          Utility.writeTemplateFile(javaClass, out, replacements);
-        }
-      }
-    }
-
-    if (eclipse != null) {
-      replacements.put("@projectName", eclipse);
-      // Build the list of extra paths
-      replacements.put("@gwtServletPath", gwtServletPath);
-      StringBuilder buf = new StringBuilder();
-      if (extraClassPaths != null) {
-        for (String path : extraClassPaths) {
-          buf.append("    <pathelement path=\"" + path + "\"/>");
-        }
-      }
-      replacements.put("@extraAntPathElements", buf.toString());
-
-      StringBuilder classpathEntries = new StringBuilder();
-      if (extraClassPaths != null) {
-        for (String path : extraClassPaths) {
-          File f = new File(path);
-
-          if (!f.exists()) {
-            throw new FileNotFoundException("extraClassPath: " + path
-                + " must be present before .launch file can be created.");
-          }
-          // Handle both .jar files and paths
-          String kindString;
-          if (f.isDirectory()) {
-            kindString = "output";
-          } else if (path.endsWith(".jar")) {
-            kindString = "lib";
-          } else {
-            throw new RuntimeException("Don't know how to handle path: " + path
-                + ". It doesn't appear to be a directory or a .jar file");
-          }
-          classpathEntries.append("\n   <classpathentry kind=\"");
-          classpathEntries.append(kindString);
-          classpathEntries.append("\" path=\"");
-          classpathEntries.append(path);
-          classpathEntries.append("\"/>");
-        }
-      }
-      replacements.put("@eclipseClassPathEntries", classpathEntries.toString());
-
-      /*
-       * create an ant file, an eclipse .project, an eclipse .classpath, and an
-       * eclipse launch-config
-       */
-      FileCreator fileCreators[] = new FileCreator[] {
-          new FileCreator(outDir, "project.ant.xml", "build.xml"),
-          new FileCreator(outDir, ".project", ".project"),
-          new FileCreator(outDir, ".classpath", ".classpath"),
-          new FileCreator(outDir, "App.launch", className + ".launch"),};
-      for (FileCreator fileCreator : fileCreators) {
-        File file = Utility.createNormalFile(fileCreator.dir,
-            fileCreator.className, overwrite, ignore);
-        if (file != null) {
-          String out = Utility.getFileFromClassPath(PACKAGE_PATH
-              + fileCreator.sourceName + "src");
-          Utility.writeTemplateFile(file, out, replacements);
-        }
-      }
-    }
-  }
-
-  private static String createExtraModuleInherits(List<String> modules) {
-    if (modules == null) {
-      return "";
-    }
-    // Create an <inherits> tag in the gwt.xml file for each extra module
-    StringBuilder buf = new StringBuilder();
-    for (String module : modules) {
-      buf.append("\n  <inherits name=\"");
-      buf.append(module);
-      buf.append("\" />");
-    }
-    return buf.toString();
-  }
-
-  private ArgHandlerAddToClassPath classPathHandler = new ArgHandlerAddToClassPath();
-  private String eclipse = null;
-  private String fullClassName = null;
-  private boolean ignore = false;
-  private ArgHandlerAddModule moduleHandler = new ArgHandlerAddModule();
-  private File outDir;
-  private boolean overwrite = false;
-  private String newModuleName = null;
-
-  protected ApplicationCreator() {
-
-    registerHandler(new ArgHandlerEclipse() {
-      @Override
-      public String getPurpose() {
-        return "Creates an ant file, an eclipse project, and a launch config";
-      }
-
-      @Override
-      public boolean setString(String str) {
-        eclipse = str;
-        return true;
-      }
-    });
-
-    registerHandler(new ArgHandlerOutDir() {
-      @Override
-      public void setDir(File dir) {
-        outDir = dir;
-      }
-    });
-
-    registerHandler(new ArgHandlerOverwrite() {
-      @Override
-      public boolean setFlag() {
-        if (ignore) {
-          System.err.println("-overwrite cannot be used with -ignore");
-          return false;
-        }
-        overwrite = true;
-        return true;
-      }
-    });
-
-    registerHandler(new ArgHandlerIgnore() {
-      @Override
-      public boolean setFlag() {
-        if (overwrite) {
-          System.err.println("-ignore cannot be used with -overwrite");
-          return false;
-        }
-        ignore = true;
-        return true;
-      }
-    });
-
-    // handler to process newModuleName argument
-    registerHandler(new ArgHandlerString() {
-      @Override
-      public String[] getDefaultArgs() {
-        return null; // later reset to moduleName
-      }
-
-      @Override
-      public String getPurpose() {
-        return "Specifies the new name of the module";
-      }
-
-      @Override
-      public String getTag() {
-        return "-moduleName";
-      }
-
-      @Override
-      public String[] getTagArgs() {
-        return new String[] {"moduleName"};
-      }
-
-      @Override
-      public boolean setString(String str) {
-        newModuleName = str;
-        return true;
-      }
-    });
-
-    registerHandler(new ArgHandlerAppClass());
-    registerHandler(classPathHandler);
-    registerHandler(moduleHandler);
-  }
-
-  protected boolean run() {
-    try {
-      createApplication(fullClassName, outDir, eclipse, overwrite, ignore,
-          classPathHandler.getExtraClassPathList(),
-          moduleHandler.getExtraModuleList(), newModuleName);
-      return true;
-    } catch (IOException e) {
-      System.err.println(e.getClass().getName() + ": " + e.getMessage());
-      return false;
-    }
-  }
-
 }
diff --git a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
index 4f6fcaf..03f9a70 100644
--- a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>@gwtModuleDtd
-<module rename-to='@newModuleName'>
+<module rename-to='@renameTo'>
   <!-- Inherit the core Web Toolkit stuff.                        -->
   <inherits name='com.google.gwt.user.User'/>
 
@@ -10,8 +10,8 @@
   <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
   <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->
 
-  <!-- Other module inherits                                      -->@extraModuleInherits
+  <!-- Other module inherits                                      -->
 
   <!-- Specify the app entry point class.                         -->
-  <entry-point class='@clientPackage.@className'/>
+  <entry-point class='@clientPackage.@moduleShortName'/>
 </module>
diff --git a/user/src/com/google/gwt/user/tools/ProjectCreator.java b/user/src/com/google/gwt/user/tools/ProjectCreator.java
index 2b5f92e..09438ad 100644
--- a/user/src/com/google/gwt/user/tools/ProjectCreator.java
+++ b/user/src/com/google/gwt/user/tools/ProjectCreator.java
@@ -17,14 +17,13 @@
 
 /**
  * Legacy ProjectCreator that will let users know that they should run
- * ApplicationCreator instead.
+ * {@link WebAppCreator} instead.
  */
 public final class ProjectCreator {
 
   public static void main(String[] args) {
     System.err.println("This application no longer exists!");
-    System.err.println("It has been merged with com.google.gwt.user.tools.ApplicationCreator in gwt-user.jar");
+    System.err.println("Please see " + WebAppCreator.class.getName());
     System.exit(1);
   }
-
 }
diff --git a/user/src/com/google/gwt/user/tools/WebAppCreator.java b/user/src/com/google/gwt/user/tools/WebAppCreator.java
new file mode 100644
index 0000000..d324a83
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/WebAppCreator.java
@@ -0,0 +1,264 @@
+/*
+ * 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.user.tools;
+
+import com.google.gwt.dev.About;
+import com.google.gwt.dev.ArgProcessorBase;
+import com.google.gwt.dev.Compiler;
+import com.google.gwt.dev.HostedMode;
+import com.google.gwt.dev.util.Util;
+import com.google.gwt.user.tools.util.ArgHandlerIgnore;
+import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
+import com.google.gwt.user.tools.util.CreatorUtilities;
+import com.google.gwt.util.tools.ArgHandlerExtra;
+import com.google.gwt.util.tools.ArgHandlerOutDir;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Creates a GWT application skeleton.
+ */
+public final class WebAppCreator {
+
+  class ArgProcessor extends ArgProcessorBase {
+
+    private final class ArgHandlerOutDirExtension extends ArgHandlerOutDir {
+      @Override
+      public void setDir(File dir) {
+        outDir = dir;
+      }
+    }
+
+    public ArgProcessor() {
+      registerHandler(new ArgHandlerOverwriteExtension());
+      registerHandler(new ArgHandlerIgnoreExtension());
+      registerHandler(new ArgHandlerModuleName());
+      registerHandler(new ArgHandlerOutDirExtension());
+    }
+
+    @Override
+    protected String getName() {
+      return WebAppCreator.class.getName();
+    }
+  }
+
+  private final class ArgHandlerIgnoreExtension extends ArgHandlerIgnore {
+    @Override
+    public boolean setFlag() {
+      if (overwrite) {
+        System.err.println("-ignore cannot be used with -overwrite");
+        return false;
+      }
+      ignore = true;
+      return true;
+    }
+  }
+
+  /*
+   * Arguments for the application creator.
+   */
+
+  private final class ArgHandlerModuleName extends ArgHandlerExtra {
+    @Override
+    public boolean addExtraArg(String arg) {
+      if (moduleName != null) {
+        System.err.println("Too many arguments.");
+        return false;
+      }
+
+      if (!CreatorUtilities.isValidModuleName(arg)) {
+        System.err.println("'"
+            + arg
+            + "' does not appear to be a valid fully-qualified Java class name.");
+        return false;
+      }
+
+      moduleName = arg;
+      return true;
+    }
+
+    @Override
+    public String getPurpose() {
+      return "The name of the module to create (fully-qualified Java class name)";
+    }
+
+    @Override
+    public String[] getTagArgs() {
+      return new String[] {"moduleName"};
+    }
+
+    @Override
+    public boolean isRequired() {
+      return true;
+    }
+  }
+
+  private final class ArgHandlerOverwriteExtension extends ArgHandlerOverwrite {
+    @Override
+    public boolean setFlag() {
+      if (ignore) {
+        System.err.println("-overwrite cannot be used with -ignore");
+        return false;
+      }
+      overwrite = true;
+      return true;
+    }
+  }
+
+  private static final class FileCreator {
+    private final String destName;
+    private final File destDir;
+    private final String sourceName;
+
+    public FileCreator(File destDir, String destName, String sourceName) {
+      this.destDir = destDir;
+      this.sourceName = sourceName;
+      this.destName = destName;
+    }
+  }
+
+  public static void main(String[] args) {
+    WebAppCreator creator = new WebAppCreator();
+    ArgProcessor argProcessor = creator.new ArgProcessor();
+    if (argProcessor.processArgs(args)) {
+      if (creator.run()) {
+        return;
+      }
+    }
+    System.exit(1);
+  }
+
+  /**
+   * @param moduleName name of the fully-qualified GWT module to create as an
+   *          Application.
+   * @param outDir Where to put the output files
+   * @param overwrite Overwrite an existing files if they exist.
+   * @param ignore Ignore existing files if they exist.
+   * @throws IOException
+   */
+  static void createApplication(String moduleName, File outDir,
+      boolean overwrite, boolean ignore) throws IOException {
+
+    // Figure out the installation directory
+    String installPath = Utility.getInstallPath();
+    String gwtUserPath = installPath + '/' + "gwt-user.jar";
+    String gwtDevPath = installPath + '/' + Utility.getDevJarName();
+    String gwtServletPath = installPath + '/' + "gwt-servlet.jar";
+
+    // Public builds generate a DTD reference.
+    String gwtModuleDtd = "";
+    if (!About.GWT_VERSION_NUM.endsWith(".999")
+        && !About.GWT_VERSION_NUM.startsWith("0.0")) {
+      gwtModuleDtd = "\n<!DOCTYPE module PUBLIC \"-//Google Inc.//DTD Google Web Toolkit "
+          + About.GWT_VERSION_NUM
+          + "//EN\" \"http://google-web-toolkit.googlecode.com/svn/tags/"
+          + About.GWT_VERSION_NUM + "/distro-source/core/src/gwt-module.dtd\">";
+    }
+
+    // Figure out what platform we're on
+    boolean isMacOsX = gwtDevPath.substring(gwtDevPath.lastIndexOf('/') + 1).indexOf(
+        "mac") >= 0;
+
+    // Compute module package and name.
+    int pos = moduleName.lastIndexOf('.');
+    String modulePackageName = moduleName.substring(0, pos);
+    String moduleShortName = moduleName.substring(pos + 1);
+
+    // Compute module name and directories
+    File srcDir = Utility.getDirectory(outDir, "src", true);
+    File warDir = Utility.getDirectory(outDir, "war", true);
+    File webInfDir = Utility.getDirectory(warDir, "WEB-INF", true);
+    File moduleDir = Utility.getDirectory(srcDir, modulePackageName.replace(
+        '.', '/'), true);
+    File clientDir = Utility.getDirectory(moduleDir, "client", true);
+    File serverDir = Utility.getDirectory(moduleDir, "server", true);
+
+    // Create a map of replacements
+    Map<String, String> replacements = new HashMap<String, String>();
+    replacements.put("@moduleShortName", moduleShortName);
+    replacements.put("@moduleName", moduleName);
+    replacements.put("@clientPackage", modulePackageName + ".client");
+    replacements.put("@serverPackage", modulePackageName + ".server");
+    replacements.put("@gwtUserPath", gwtUserPath);
+    replacements.put("@gwtDevPath", gwtDevPath);
+    replacements.put("@gwtServletPath", gwtServletPath);
+    replacements.put("@gwtVersion", About.GWT_VERSION_NUM);
+    replacements.put("@gwtModuleDtd", gwtModuleDtd);
+    replacements.put("@shellClass", HostedMode.class.getName());
+    replacements.put("@compileClass", Compiler.class.getName());
+    replacements.put("@startupUrl", moduleShortName + ".html");
+    replacements.put("@antVmargs", isMacOsX
+        ? "\n<jvmarg value=\"-XstartOnFirstThread\"/>" : "");
+    replacements.put("@vmargs", isMacOsX ? "&#10;-XstartOnFirstThread" : "");
+    replacements.put("@renameTo", moduleShortName.toLowerCase());
+
+    List<FileCreator> files = new ArrayList<FileCreator>();
+    files.add(new FileCreator(moduleDir, moduleShortName + ".gwt.xml",
+        "Module.gwt.xml"));
+    files.add(new FileCreator(warDir, moduleShortName + ".html", "AppHtml.html"));
+    files.add(new FileCreator(warDir, moduleShortName + ".css", "AppCss.css"));
+    files.add(new FileCreator(webInfDir, "web.xml", "web.xml"));
+    files.add(new FileCreator(clientDir, moduleShortName + ".java",
+        "AppClassTemplate.java"));
+    files.add(new FileCreator(clientDir, "EchoService" + ".java",
+        "RpcClientTemplate.java"));
+    files.add(new FileCreator(clientDir, "EchoServiceAsync" + ".java",
+        "RpcAsyncClientTemplate.java"));
+    files.add(new FileCreator(serverDir, "EchoServiceImpl" + ".java",
+        "RpcServerTemplate.java"));
+    files.add(new FileCreator(outDir, "build.xml", "project.ant.xml"));
+    files.add(new FileCreator(outDir, ".project", ".project"));
+    files.add(new FileCreator(outDir, ".classpath", ".classpath"));
+    files.add(new FileCreator(outDir, moduleShortName + ".launch", "App.launch"));
+
+    for (FileCreator fileCreator : files) {
+      File file = Utility.createNormalFile(fileCreator.destDir,
+          fileCreator.destName, overwrite, ignore);
+      if (file != null) {
+        URL url = WebAppCreator.class.getResource(fileCreator.sourceName
+            + "src");
+        if (url == null) {
+          throw new FileNotFoundException(fileCreator.sourceName + "src");
+        }
+        String data = Util.readURLAsString(url);
+        Utility.writeTemplateFile(file, data, replacements);
+      }
+    }
+  }
+
+  private boolean ignore = false;
+  private String moduleName;
+  private File outDir;
+  private boolean overwrite = false;
+
+  protected boolean run() {
+    try {
+      createApplication(moduleName, outDir, overwrite, ignore);
+      return true;
+    } catch (IOException e) {
+      System.err.println(e.getClass().getName() + ": " + e.getMessage());
+      return false;
+    }
+  }
+}
diff --git a/user/src/com/google/gwt/user/tools/project.ant.xmlsrc b/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
index f130c69..33912a6 100644
--- a/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
@@ -1,10 +1,9 @@
 <?xml version="1.0" encoding="utf-8" ?>
-<project name="@projectName" default="build" basedir=".">
+<project name="@moduleShortName" default="build" basedir=".">
 
   <path id="project.class.path">
     <pathelement location="war/WEB-INF/classes"/>
     <pathelement path="@gwtUserPath"/>
-@extraAntPathElements
     <!-- Add any additional non-server libs (such as JUnit) -->
     <fileset dir="war/WEB-INF/lib">
       <include name="**/*.jar"/>
@@ -60,7 +59,7 @@
 
   <target name="clean" description="Cleans this project">
     <delete dir="war/WEB-INF/classes" failonerror="false" />
-    <delete dir="war/@newModuleName" failonerror="false" />
+    <delete dir="war/@renameTo" failonerror="false" />
   </target>
 
 </project>
diff --git a/user/src/com/google/gwt/user/tools/util/CreatorUtilities.java b/user/src/com/google/gwt/user/tools/util/CreatorUtilities.java
index e21775b..2c9a802 100644
--- a/user/src/com/google/gwt/user/tools/util/CreatorUtilities.java
+++ b/user/src/com/google/gwt/user/tools/util/CreatorUtilities.java
@@ -76,7 +76,7 @@
       }
 
       String lcPath = path.toLowerCase();
-      
+
       if (f.isDirectory()) {
         // For a directory, we assume it contains compiled class files
         buf.append("<listEntry value=\"&lt;?xml version=&quot;1.0&quot; ");
@@ -103,6 +103,14 @@
   }
 
   /**
+   * Returns <code>true</code> if <code>moduleName</code> is a valid module
+   * name.
+   */
+  public static boolean isValidModuleName(String moduleName) {
+    return moduleName.matches("[\\w]+(\\.[\\w]+)+");
+  }
+
+  /**
    * Check to see that the userJar and pathList files all exist, and that the
    * moduleList entries can be found within the jars.
    * 
diff --git a/user/src/com/google/gwt/user/tools/web.xmlsrc b/user/src/com/google/gwt/user/tools/web.xmlsrc
index 60ade4d..62ca7c8 100644
--- a/user/src/com/google/gwt/user/tools/web.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/web.xmlsrc
@@ -8,7 +8,7 @@
   
   <servlet-mapping>
     <servlet-name>echoServlet</servlet-name>
-    <url-pattern>/@newModuleName/echo</url-pattern>
+    <url-pattern>/@renameTo/echo</url-pattern>
   </servlet-mapping>
 
 </web-app>