@Override
  public void doFreemarkerGenerate() throws IOException, TemplateException {
    if (!isUpToDate()) {
      EnunciateFreemarkerModel model = getModel();
      // generate the rpc request/response beans.
      for (WsdlInfo wsdlInfo : model.getNamespacesToWSDLs().values()) {
        for (EndpointInterface ei : wsdlInfo.getEndpointInterfaces()) {
          for (WebMethod webMethod : ei.getWebMethods()) {
            for (WebMessage webMessage : webMethod.getMessages()) {
              if (webMessage instanceof RPCInputMessage) {
                model.put("message", webMessage);
                processTemplate(getRPCRequestBeanTemplateURL(), model);
              } else if (webMessage instanceof RPCOutputMessage) {
                model.put("message", webMessage);
                processTemplate(getRPCResponseBeanTemplateURL(), model);
              }
            }
          }
        }
      }

      model.put("xfireBeansImport", getXfireBeansImport());
      model.put("docsDir", enunciate.getProperty("docs.webapp.dir"));
      processTemplate(getXfireServletTemplateURL(), model);
      processTemplate(getParameterNamesTemplateURL(), model);
    } else {
      info("Skipping generation of XFire support classes as everything appears up-to-date....");
    }

    getEnunciate()
        .addArtifact(new FileArtifact(getName(), "xfire-server.src.dir", getGenerateDir()));
    getEnunciate().addAdditionalSourceRoot(getGenerateDir());
  }
  // Inherited.
  @Override
  public void initModel(EnunciateFreemarkerModel model) {
    super.initModel(model);

    if (!isDisabled()) {
      EnunciateConfiguration config = model.getEnunciateConfig();
      for (WsdlInfo wsdlInfo : model.getNamespacesToWSDLs().values()) {
        for (EndpointInterface ei : wsdlInfo.getEndpointInterfaces()) {
          String path = "/soap/" + ei.getServiceName();
          if (config != null) {
            path = config.getDefaultSoapSubcontext() + '/' + ei.getServiceName();
            if (config.getSoapServices2Paths().containsKey(ei.getServiceName())) {
              path = config.getSoapServices2Paths().get(ei.getServiceName());
            }
          }

          ei.putMetaData("soapPath", path);
        }
      }

      if (!exporterFound) {
        warn(
            "The Enunciate XFire runtime wasn't found on the Enunciate classpath. This could be fatal to the runtime application.");
      }
    }
  }
  @Override
  protected void doBuild() throws EnunciateException, IOException {
    super.doBuild();

    File webappDir = getBuildDir();
    webappDir.mkdirs();
    File webinf = new File(webappDir, "WEB-INF");
    getEnunciate()
        .copyFile(
            new File(getGenerateDir(), "xfire-servlet.xml"), new File(webinf, "xfire-servlet.xml"));
    getEnunciate()
        .copyFile(
            new File(getGenerateDir(), "enunciate-soap-parameter-names.properties"),
            new File(new File(webinf, "classes"), "enunciate-soap-parameter-names.properties"));

    BaseWebAppFragment webappFragment = new BaseWebAppFragment(getName());
    webappFragment.setBaseDir(webappDir);
    WebAppComponent servletComponent = new WebAppComponent();
    servletComponent.setName("xfire");
    servletComponent.setClassname(DispatcherServlet.class.getName());
    TreeSet<String> urlMappings = new TreeSet<String>();
    ArrayList<WebAppComponent> filters = new ArrayList<WebAppComponent>();
    for (WsdlInfo wsdlInfo : getModel().getNamespacesToWSDLs().values()) {
      TreeSet<String> urlMappingsForNs = new TreeSet<String>();
      for (EndpointInterface endpointInterface : wsdlInfo.getEndpointInterfaces()) {
        urlMappingsForNs.add(String.valueOf(endpointInterface.getMetaData().get("soapPath")));
      }
      urlMappings.addAll(urlMappingsForNs);

      String redirectLocation = (String) wsdlInfo.getProperty("redirectLocation");
      if (redirectLocation != null) {
        WebAppComponent wsdlFilter = new WebAppComponent();
        wsdlFilter.setName("wsdl-redirect-filter-" + wsdlInfo.getId());
        wsdlFilter.setClassname(WSDLRedirectFilter.class.getName());
        wsdlFilter.addInitParam(WSDLRedirectFilter.WSDL_LOCATION_PARAM, redirectLocation);
        wsdlFilter.setUrlMappings(urlMappingsForNs);
        filters.add(wsdlFilter);
      }
    }
    servletComponent.setUrlMappings(urlMappings);
    webappFragment.setServlets(Arrays.asList(servletComponent));
    webappFragment.setFilters(filters);
    getEnunciate().addWebAppFragment(webappFragment);
  }