/** Render column headers either in single row or nested if a columnGroup is defined */
  protected void encodeThead(FacesContext context, DataTable table) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    ColumnGroup group = table.getColumnGroup("header");

    writer.startElement("thead", null);
    writer.writeAttribute("id", table.getClientId(context) + "_head", null);

    if (group != null && group.isRendered()) {

      for (UIComponent child : group.getChildren()) {
        if (child.isRendered() && child instanceof Row) {
          Row headerRow = (Row) child;

          writer.startElement("tr", null);

          for (UIComponent headerRowChild : headerRow.getChildren()) {
            if (headerRowChild.isRendered() && headerRowChild instanceof Column) {
              encodeColumnHeader(context, table, (Column) headerRowChild);
            }
          }

          writer.endElement("tr");
        }
      }

    } else {
      writer.startElement("tr", null);
      writer.writeAttribute("role", "row", null);

      for (UIColumn column : table.getColumns()) {
        if (column instanceof Column) {
          encodeColumnHeader(context, table, column);
        } else if (column instanceof DynamicColumn) {
          DynamicColumn dynamicColumn = (DynamicColumn) column;
          dynamicColumn.applyModel();

          encodeColumnHeader(context, table, dynamicColumn);
        }
      }

      writer.endElement("tr");
    }

    encodeFrozenRows(context, table);

    writer.endElement("thead");
  }
  protected void encodeTFoot(FacesContext context, DataTable table) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    ColumnGroup group = table.getColumnGroup("footer");

    writer.startElement("tfoot", null);

    if (group != null && group.isRendered()) {

      for (UIComponent child : group.getChildren()) {
        if (child.isRendered() && child instanceof Row) {
          Row footerRow = (Row) child;

          writer.startElement("tr", null);

          for (UIComponent footerRowChild : footerRow.getChildren()) {
            if (footerRowChild.isRendered() && footerRowChild instanceof Column) {
              encodeColumnFooter(context, table, (Column) footerRowChild);
            }
          }

          writer.endElement("tr");
        }
      }

    } else if (table.hasFooterColumn()) {
      writer.startElement("tr", null);

      for (UIColumn column : table.getColumns()) {
        if (column instanceof Column) {
          encodeColumnFooter(context, table, column);
        } else if (column instanceof DynamicColumn) {
          DynamicColumn dynamicColumn = (DynamicColumn) column;
          dynamicColumn.applyModel();

          encodeColumnFooter(context, table, dynamicColumn);
        }
      }

      writer.endElement("tr");
    }

    writer.endElement("tfoot");
  }
  public void encodeRow(
      FacesContext context, Row row, String columnRole, String rowClass, String columnClass)
      throws IOException {
    ResponseWriter writer = context.getResponseWriter();

    writer.startElement("tr", null);
    if (shouldWriteId(row)) {
      writer.writeAttribute("id", row.getClientId(context), null);
    }

    writer.writeAttribute("class", rowClass, null);
    writer.writeAttribute("role", "row", null);

    for (UIComponent child : row.getChildren()) {
      if (child instanceof Column && child.isRendered()) {
        Column column = (Column) child;
        String userStyleClass = column.getStyleClass();
        String styleClass =
            (userStyleClass == null) ? columnClass : columnClass + " " + userStyleClass;

        writer.startElement("td", null);
        if (shouldWriteId(column)) {
          writer.writeAttribute("id", column.getClientId(context), null);
        }
        writer.writeAttribute("role", columnRole, null);
        writer.writeAttribute("class", styleClass, null);

        if (column.getStyle() != null) writer.writeAttribute("style", column.getStyle(), null);
        if (column.getColspan() > 1) writer.writeAttribute("colspan", column.getColspan(), null);
        if (column.getRowspan() > 1) writer.writeAttribute("rowspan", column.getRowspan(), null);

        renderChildren(context, column);

        writer.endElement("td");
      }
    }

    writer.endElement("tr");
  }