private String _getTrNumberConverter(
      FacesContext context, UIComponent component, Map<?, ?> messages) {
    StringBuilder outBuffer = new StringBuilder(250);

    if (this.isIntegerOnly() && this.getPattern() == null && "number".equals(this.getType())) {
      outBuffer.append("new TrIntegerConverter(");
      outBuffer.append("null,null,0,");
      outBuffer.append(IntegerUtils.getString(Integer.MAX_VALUE));
      outBuffer.append(',');
      outBuffer.append(IntegerUtils.getString(Integer.MIN_VALUE));
      outBuffer.append(")");
    } else {

      Object[] params = _getClientConstructorParams(context, messages);

      outBuffer.append("new TrNumberConverter(");

      for (int i = 0; i < params.length; i++) {
        try {
          JsonUtils.writeObject(outBuffer, params[i], false);
        } catch (Exception e) {
          outBuffer.append("null");
        }
        if (i < params.length - 1) outBuffer.append(',');
      }
      outBuffer.append(')');
    }
    return outBuffer.toString();
  }
  protected void renderImage(
      UIXRenderingContext context,
      UINode node,
      ImageProviderResponse response,
      boolean hasMap,
      String mapName,
      Object shortDesc,
      Object destination)
      throws IOException {
    assert node != null;

    boolean hasLink = (destination != null);
    Object longDesc = getLongDesc(context, node);
    String imageStyle = getImageStyle(context, node);
    String imageStyleClass = getImageStyleClass(context, node);

    ResponseWriter writer = context.getResponseWriter();
    UIComponent component = (node == null) ? null : node.getUIComponent();

    if (hasLink) {
      writer.startElement("a", component);
      renderEncodedActionURI(context, "href", destination);
      renderAttribute(context, node, "target", TARGET_FRAME_ATTR);

      // Don't render access key on Netscape... Netscape doesn't
      // support access keys - if this ever changes, it would
      // be confusing if we rendered the accessKey attr without
      // also underlining the access key in the corresponding text.
      if (!isNetscape(context)) {
        renderButtonAccessKey(context, node);
      }

      // If we have a link, we render the standard attributes on
      // the link instead of on the image
      renderAttributes(context, node);
    }

    writer.startElement("img", component);

    // Write out all of the standard attrs
    if (!hasLink) renderAttributes(context, node);

    // Write out the image url
    writeCacheImageURI(context, "src", response.getImageURI());

    // Write out the description attrs.
    renderAltAndTooltipForImage(context, shortDesc);
    renderAttribute(context, "longdesc", longDesc);

    // Null out the border
    renderAttribute(context, "border", "0");

    // Render alignment.  Is this necessary?
    renderHAlign(context, node);

    // This is to address bug #2047577
    // Instead of adding an attribute to control placement of the button,
    // we just force it to middle (which is what everybody wants anyway).
    // We have to make sure we don't put the align attribute in twice.
    // We allow the hAlign attribute to take precedence.
    if (node.getAttributeValue(context, H_ALIGN_ATTR) == null) {
      Object valign = getVAlign(context, node);
      if (valign != null) renderAttribute(context, "align", valign);
    }

    // Render the width/height
    int width = response.getWidth();
    int height = response.getHeight();

    if (width != ImageProviderResponse.UNKNOWN_SIZE)
      renderAttribute(context, "width", IntegerUtils.getString(width));
    if (height != ImageProviderResponse.UNKNOWN_SIZE)
      renderAttribute(context, "height", IntegerUtils.getString(height));

    // The image map
    if (hasMap) writer.writeAttribute("usemap", "#" + mapName, null);

    if (imageStyle != null) renderAttribute(context, "style", imageStyle);
    if (imageStyleClass != null) renderStyleClassAttribute(context, imageStyleClass);

    writer.endElement("img");

    if (hasLink) writer.endElement("a");
  }