/** {@inheritDoc} */
  @Override
  public void openDoc(final PrintWriter writer) {
    UIContext uic = UIContextHolder.getCurrent();
    String title = getApplicationTitle(uic);

    writer.write(XMLUtil.getXMLDeclarationWithThemeXslt(uic));
    // Provide temporary backward compatibility with   while
    // applications convert to be XML compliant.
    writer.write(XMLUtil.DOC_TYPE);
    writer.write(
        "\n<ui:root title=\""
            + WebUtilities.encode(title)
            + "\" "
            + XMLUtil.STANDARD_NAMESPACES
            + ">");
  }
  /**
   * Retrieves the application title for the given context. This mess is required due to WWindow
   * essentially existing as a separate UI root. If WWindow is eventually removed, then we can just
   * retrieve the title from the root WApplication.
   *
   * @param uic the context to check.
   * @return the current application title.
   */
  private String getApplicationTitle(final UIContext uic) {
    WComponent root = uic.getUI();
    String title = root instanceof WApplication ? ((WApplication) root).getTitle() : null;

    Map<String, String> params = uic.getEnvironment().getHiddenParameters();
    String target = params.get(WWindow.WWINDOW_REQUEST_PARAM_KEY);

    if (target != null) {
      ComponentWithContext targetComp = WebUtilities.getComponentById(target, true);

      if (targetComp != null && targetComp.getComponent() instanceof WWindow) {
        try {
          UIContextHolder.pushContext(targetComp.getContext());
          title = ((WWindow) targetComp.getComponent()).getTitle();
        } finally {
          UIContextHolder.popContext();
        }
      }
    }

    return title == null ? "" : title;
  }
  /**
   * Paint the ajax container response.
   *
   * @param renderContext the render context
   * @param operation the ajax operation
   */
  private void paintContainerResponse(
      final RenderContext renderContext, final AjaxOperation operation) {
    WebXmlRenderContext webRenderContext = (WebXmlRenderContext) renderContext;
    XmlStringBuilder xml = webRenderContext.getWriter();

    // Get trigger's context
    ComponentWithContext trigger = AjaxHelper.getCurrentTriggerAndContext();
    if (trigger == null) {
      throw new SystemException("No context available for trigger " + operation.getTriggerId());
    }

    xml.appendTagOpen("ui:ajaxTarget");
    xml.appendAttribute("id", operation.getTargetContainerId());
    xml.appendAttribute("action", "replaceContent");
    xml.appendClose();

    // Paint targets - Assume targets are in the same context as the trigger
    UIContextHolder.pushContext(trigger.getContext());
    try {
      for (String targetId : operation.getTargets()) {
        ComponentWithContext target = null;
        if (targetId.equals(operation.getTriggerId())) {
          target = trigger;
        } else {
          target = WebUtilities.getComponentById(targetId, true);
          if (target == null) {
            log.warn("Could not find ajax target to render " + target);
            continue;
          }
        }
        target.getComponent().paint(renderContext);
      }
    } finally {
      UIContextHolder.popContext();
    }

    xml.appendEndTag("ui:ajaxTarget");
  }