private static String getChainedHandler(
      FacesContext context,
      UIComponent component,
      List<ClientBehavior> behaviors,
      Collection<ClientBehaviorContext.Parameter> params,
      String behaviorEventName,
      String userHandler) {

    StringBuilder builder = new StringBuilder(100);
    builder.append("jsf.util.chain(this,event,");

    appendScriptToChain(builder, userHandler);

    boolean submitting =
        appendBehaviorsToChain(builder, context, component, behaviors, behaviorEventName, params);

    boolean hasParams = ((null != params) && !params.isEmpty());

    if (!submitting && hasParams) {
      String submitHandler = getSubmitHandler(context, component, params, false);

      appendScriptToChain(builder, submitHandler);

      submitting = true;
    }

    builder.append(")");

    if (submitting && ("action".equals(behaviorEventName) || "click".equals(behaviorEventName))) {
      builder.append(";return false");
    }

    return builder.toString();
  }
  private static void appendScriptToChain(StringBuilder builder, String script) {

    if ((script == null) || (script.length() == 0)) {
      return;
    }

    if (builder.charAt(builder.length() - 1) != ',') builder.append(',');

    appendQuotedValue(builder, script);
  }
  private static String getSubmitHandler(
      FacesContext context,
      UIComponent component,
      Collection<ClientBehaviorContext.Parameter> params,
      boolean preventDefault) {

    StringBuilder builder = new StringBuilder(256);

    String formClientId = getFormClientId(component, context);
    String componentClientId = component.getClientId(context);

    builder.append("qab.sf(document.getElementById('");
    builder.append(formClientId);
    builder.append("'),{");

    appendProperty(builder, componentClientId, componentClientId);

    if ((null != params) && (!params.isEmpty())) {
      for (ClientBehaviorContext.Parameter param : params) {
        appendProperty(builder, param.getName(), param.getValue());
      }
    }

    builder.append("})");

    if (preventDefault) {
      builder.append(";return false");
    }

    return builder.toString();
  }
  private static void appendQuotedValue(StringBuilder builder, String script) {

    builder.append("'");

    int length = script.length();

    for (int i = 0; i < length; i++) {
      char c = script.charAt(i);

      if (c == '\'' || c == '\\') {
        builder.append('\\');
      }

      builder.append(c);
    }

    builder.append("'");
  }
  public static String findClientIds(String ids, UIComponent component, FacesContext context)
      throws IOException {
    if (ids == null) return null;

    StringBuilder clientIds = new StringBuilder();
    String[] idlist = ids.split("[\\s]");
    for (String id : idlist) {
      if (!id.startsWith("@")) {
        UIComponent found = component.findComponent(id);
        if (found != null) {
          if (clientIds.length() > 0) clientIds.append(" ");
          clientIds.append(found.getClientId(context));
        } else {
          throw new IOException("Cannot find id " + id + " within components NamingContainer");
        }
      }
    }

    return clientIds.toString();
  }
  public static void appendProperty(
      StringBuilder builder, String name, Object value, boolean quoteValue) {

    if ((null == name) || (name.length() == 0)) throw new IllegalArgumentException();

    char lastChar = builder.charAt(builder.length() - 1);
    if ((lastChar != ',') && (lastChar != '{')) builder.append(',');

    appendQuotedValue(builder, name);
    builder.append(":");

    if (value == null) {
      builder.append("''");
    } else if (quoteValue) {
      appendQuotedValue(builder, value.toString());
    } else {
      builder.append(value.toString());
    }
  }