/**
   * Create or retrieve an instance of <code>LifecycleBean</code> and push it on to the object
   * stack.
   *
   * @param namespace the namespace URI of the matching element, or an empty string if the parser is
   *     not namespace aware or the element has no namespace
   * @param name the local name if the parser is namespace aware, or just the element name otherwise
   * @param attributes The attribute list of this element
   * @exception IllegalStateException if the parent stack element is not of type FacesConfigBean
   */
  public void begin(String namespace, String name, Attributes attributes) throws Exception {

    FacesConfigBean fcb = null;
    try {
      fcb = (FacesConfigBean) digester.peek();
    } catch (Exception e) {
      throw new IllegalStateException("No parent FacesConfigBean on object stack");
    }
    LifecycleBean lb = fcb.getLifecycle();
    if (lb == null) {
      if (digester.getLogger().isDebugEnabled()) {
        digester
            .getLogger()
            .debug("[LifecycleRule]{" + digester.getMatch() + "} New " + CLASS_NAME);
      }
      Class clazz = digester.getClassLoader().loadClass(CLASS_NAME);
      lb = (LifecycleBean) clazz.newInstance();
      fcb.setLifecycle(lb);
    } else {
      if (digester.getLogger().isDebugEnabled()) {
        digester
            .getLogger()
            .debug("[LifecycleRule]{" + digester.getMatch() + "} Old " + CLASS_NAME);
      }
    }
    digester.push(lb);
  }
  private void writeClassBody(CodeWriter writer, FacesConfigBean bean) throws Exception {
    writer.indent();
    writer.fwrite(
        "private static Map<String,Attribute[]> ATTRIBUTE_LOOKUP=CollectionsUtils.<String,Attribute[]>map()\n");
    writer.indent();

    ComponentBean[] components = bean.getComponents();
    List<String> keys = new ArrayList<String>();
    for (int i = 0, len = components.length; i < len; i++) {
      ComponentBean comp = components[i];
      if (!comp.getComponentClass().contains("Html")) {
        continue;
      }
      String type = comp.getRendererType();
      if (type != null) {
        String family = comp.getBaseComponentType();
        type = type.substring(type.lastIndexOf('.') + 1);
        family = family.substring(family.lastIndexOf('.') + 1);
        String key = family + type;
        PropertyBean[] props = comp.getProperties();
        boolean attributeWritten = false;
        for (int ii = 0, llen = props.length; ii < llen; ii++) {
          PropertyBean aBean = props[ii];
          if (aBean.isPassThrough()) {
            if ((key.contains("Radio") || "SelectManyCheckbox".equals(key))
                && ("style".equals(aBean.getPropertyName())
                    || ("border".equals(aBean.getPropertyName())))) {
              continue;
            }
            if (attributeWritten) {
              writer.fwrite(",attr(\"");
            } else {
              keys.add(key);
              writer.fwrite(".add(\"");
              writer.write(key);
              writer.write("\",ar(\n");
              writer.indent();
              writer.fwrite("attr(\"");
            }
            writer.write(aBean.getPropertyName());
            writer.write("\"");
            if (aBean.getBehaviors() != null && !aBean.getBehaviors().isEmpty()) {
              for (String behavior : aBean.getBehaviors()) {
                writer.write(",\"");
                String behaviorName;
                if (0 == behavior.length()) {
                  behaviorName = aBean.getPropertyName();
                  // Strip leading "on" preffix.
                  if (behaviorName.length() > 2 && behaviorName.startsWith("on")) {
                    StringBuilder buffer =
                        new StringBuilder(behaviorName.substring(2, 3).toLowerCase());
                    buffer.append(behaviorName.substring(3));
                    behaviorName = buffer.toString();
                  }
                } else {
                  behaviorName = behavior;
                }
                writer.write(behaviorName);
                writer.write("\"");
              }
            }
            writer.write(")\n");
            attributeWritten = true;
          }
          if (key.contains("Button") && "onclick".equals(aBean.getPropertyName())) {
            // reset to the original state
            aBean.setPassThrough(false);
          }
        }
        if (attributeWritten) {
          writer.outdent();
          writer.fwrite("))\n");
        }
      }
    }
    writer.fwrite(".fix();\n");

    //        writer.fwrite("ATTRIBUTE_LOOKUP = Collections.unmodifiableMap(map);\n");
    //        writer.outdent();
    //        writer.fwrite("}\n\n");
    writer.outdent();
    writer.fwrite("public enum Key {\n");
    writer.indent();
    for (int i = 0, len = keys.size(); i < len; i++) {
      String key = keys.get(i);
      writer.fwrite(key.toUpperCase() + "(\"" + key + "\")");
      if (i == (len - 1)) {
        writer.write(";\n");
      } else {
        writer.write(",\n");
      }
    }
    writer.fwrite("private String key;\n");
    writer.fwrite("Key(String key) {\n");
    writer.indent();
    writer.fwrite("this.key = key;\n");
    writer.outdent();
    writer.fwrite("}\n");
    writer.fwrite("public String value() {\n");
    writer.indent();
    writer.fwrite("return this.key;\n");
    writer.outdent();
    writer.fwrite("}\n");
    writer.outdent();
    writer.fwrite("}\n");
    writer.write("\n\n");
    writer.fwrite("public static Attribute[] getAttributes(Key key) {\n");
    writer.indent();
    writer.fwrite("return ATTRIBUTE_LOOKUP.get(key.value());\n");
    writer.outdent();
    writer.fwrite("}\n");
  }