public void encodeHiddenInput(
      ResponseWriter writer, FacesContext facesContext, UIDataTableBase dataTableBase)
      throws IOException {
    AbstractCollapsibleSubTable subTable = (AbstractCollapsibleSubTable) dataTableBase;

    String stateId = subTable.getClientId(facesContext) + STATE;

    writer.startElement(HtmlConstants.INPUT_ELEM, subTable);
    writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, stateId, null);
    writer.writeAttribute(HtmlConstants.NAME_ATTRIBUTE, stateId, null);
    writer.writeAttribute(HtmlConstants.TYPE_ATTR, HtmlConstants.INPUT_TYPE_HIDDEN, null);

    int state =
        subTable.isExpanded()
            ? AbstractCollapsibleSubTable.EXPANDED_STATE
            : AbstractCollapsibleSubTable.COLLAPSED_STATE;

    writer.writeAttribute(HtmlConstants.VALUE_ATTRIBUTE, state, null);
    writer.endElement(HtmlConstants.INPUT_ELEM);

    String optionsId = subTable.getClientId(facesContext) + OPTIONS;
    writer.startElement(HtmlConstants.INPUT_ELEM, subTable);
    writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, optionsId, null);
    writer.writeAttribute(HtmlConstants.NAME_ATTRIBUTE, optionsId, null);
    writer.writeAttribute(HtmlConstants.TYPE_ATTR, HtmlConstants.INPUT_TYPE_HIDDEN, null);
    writer.endElement(HtmlConstants.INPUT_ELEM);
  }
  protected void doDecode(FacesContext facesContext, UIComponent component) {
    AbstractCollapsibleSubTable subTable = (AbstractCollapsibleSubTable) component;

    String clientId = subTable.getClientId(facesContext);
    Map<String, String> requestMap = facesContext.getExternalContext().getRequestParameterMap();

    String optionsId = clientId + OPTIONS;
    String togglerId = requestMap.get(optionsId);

    String stateId = clientId + STATE;
    String state = (String) requestMap.get(stateId);

    boolean isExpanded = true;
    if (state != null) {
      int newValue = Integer.parseInt(state);

      if (newValue < 1) {
        isExpanded = false;
      }

      if (subTable.isExpanded() != isExpanded) {
        new CollapsibleSubTableToggleEvent(subTable, isExpanded, togglerId).queue();
      }
    }
  }
  @Override
  public void encodeTableBodyStart(
      ResponseWriter writer, FacesContext facesContext, UIDataTableBase dataTableBase)
      throws IOException {
    AbstractCollapsibleSubTable subTable = (AbstractCollapsibleSubTable) dataTableBase;

    UIDataTableBase component = findParent(subTable);
    if (component instanceof AbstractDataTable) {
      writer.startElement(HtmlConstants.TBODY_ELEMENT, null);
      writer.writeAttribute(
          HtmlConstants.ID_ATTRIBUTE,
          component.getRelativeClientId(facesContext) + ":" + subTable.getId() + TB_ROW,
          null);
      writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, getTableSkinClass(), null);

      String predefinedStyles = !subTable.isExpanded() ? DISPLAY_NONE : null;
      encodeStyle(writer, facesContext, subTable, predefinedStyles);
    }
  }