public static URL getModuleRootURL(IModule module, String host, int port, String contextRoot) {
    if (module == null || module.loadAdapter(IWebModule.class, null) == null) return null;

    IWebModule webModule = (IWebModule) module.loadAdapter(IWebModule.class, null);
    String host2 = ServerUtil.formatPossibleIpv6Address(host);
    String url = host2;
    if (!url.startsWith("http://") && !url.startsWith("https://")) { // $NON-NLS-1$ //$NON-NLS-2$
      url = "http://" + host2; // $NON-NLS-1$
    }
    if (port != 80) url += ":" + port; // $NON-NLS-1$

    if (contextRoot == null) {
      contextRoot = webModule.getContextRoot();
    }
    if (!contextRoot.equals("/") && !contextRoot.equals("./")) // $NON-NLS-1$ //$NON-NLS-2$
    url +=
          contextRoot.startsWith("/")
              ? contextRoot
              : "/" + contextRoot; // $NON-NLS-1$ //$NON-NLS-2$
    if (!url.endsWith("/")) // $NON-NLS-1$
    url += "/"; // $NON-NLS-1$

    try {
      return new URL(url);
    } catch (MalformedURLException murle) {
      return null;
    }
  }
  /** @see PublishOperation#execute(IProgressMonitor, IAdaptable) */
  public void execute(IProgressMonitor monitor, IAdaptable info) throws CoreException {
    List status = new ArrayList();

    // If parent web module
    if (module.length == 1) {
      if (!ServerUtil.isExtProject(module[0].getProject())) {
        publishDir(module[0], status, monitor);
      }
    }
    // Else a child module
    else {
      Properties p = server.loadModulePublishLocations();

      // Try to determine the URI for the child module
      IWebModule webModule = (IWebModule) module[0].loadAdapter(IWebModule.class, monitor);
      String childURI = null;
      if (webModule != null) {
        childURI = webModule.getURI(module[1]);
      }
      // Try to determine if child is binary
      IJ2EEModule childModule = (IJ2EEModule) module[1].loadAdapter(IJ2EEModule.class, monitor);
      boolean isBinary = false;
      if (childModule != null) {
        isBinary = childModule.isBinary();
      }

      if (isBinary) {
        publishArchiveModule(childURI, p, status, monitor);
      } else {
        publishJar(childURI, p, status, monitor);
      }
      server.saveModulePublishLocations(p);
    }
    throwException(status);
    server.setModulePublishState2(module, IServer.PUBLISH_STATE_NONE);
  }