boolean isInSameGroup(FacesContext context, DataTable table, int currentRowIndex) {

    table.setRowIndex(currentRowIndex);
    Object currentGroupByData = table.getSortBy();

    table.setRowIndex(currentRowIndex + 1);
    if (!table.isRowAvailable()) return false;

    Object nextGroupByData = table.getSortBy();
    if (currentGroupByData != null && nextGroupByData.equals(currentGroupByData)) {
      return true;
    }

    return false;
  }
  protected void encodeSummaryRow(FacesContext context, DataTable table, SummaryRow summaryRow)
      throws IOException {
    MethodExpression me = summaryRow.getListener();
    if (me != null) {
      me.invoke(context.getELContext(), new Object[] {table.getSortBy()});
    }

    summaryRow.encodeAll(context);
  }
  protected void encodeColumnHeader(FacesContext context, DataTable table, UIColumn column)
      throws IOException {
    if (!column.isRendered()) {
      return;
    }

    ResponseWriter writer = context.getResponseWriter();
    String clientId = column.getContainerClientId(context);
    Object tableSortBy = table.getSortBy();
    Object columnSortBy = column.getSortBy();
    boolean isSortable = columnSortBy != null;
    boolean hasFilter = column.getFilterBy() != null;
    String selectionMode = column.getSelectionMode();
    String sortIcon = null;
    boolean resizable = table.isResizableColumns() && column.isResizable();

    String columnClass =
        isSortable
            ? DataTable.COLUMN_HEADER_CLASS + " " + DataTable.SORTABLE_COLUMN_CLASS
            : DataTable.COLUMN_HEADER_CLASS;
    columnClass = hasFilter ? columnClass + " " + DataTable.FILTER_COLUMN_CLASS : columnClass;
    columnClass =
        selectionMode != null ? columnClass + " " + DataTable.SELECTION_COLUMN_CLASS : columnClass;
    columnClass = resizable ? columnClass + " " + DataTable.RESIZABLE_COLUMN_CLASS : columnClass;
    columnClass =
        column.getStyleClass() != null ? columnClass + " " + column.getStyleClass() : columnClass;

    if (isSortable) {
      if (tableSortBy != null) {
        if (table.isMultiSort()) {
          List<SortMeta> sortMeta = table.getMultiSortMeta();

          if (sortMeta != null) {
            for (SortMeta meta : sortMeta) {
              sortIcon =
                  resolveDefaultSortIcon(
                      columnSortBy, meta.getColumn().getSortBy(), meta.getSortOrder().name());

              if (sortIcon != null) {
                break;
              }
            }
          }
        } else {
          sortIcon = resolveDefaultSortIcon(columnSortBy, tableSortBy, table.getSortOrder());
        }
      }

      if (sortIcon == null) sortIcon = DataTable.SORTABLE_COLUMN_ICON_CLASS;
      else columnClass += " ui-state-active";
    }

    String style = column.getStyle();
    String width = column.getWidth();
    if (width != null) {
      String unit = width.endsWith("%") ? "" : "px";
      if (style != null) style = style + ";width:" + width + unit;
      else style = "width:" + width + unit;
    }

    writer.startElement("th", null);
    writer.writeAttribute("id", clientId, null);
    writer.writeAttribute("class", columnClass, null);
    writer.writeAttribute("role", "columnheader", null);

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

    if (hasFilter) {
      table.enableFiltering();

      String filterPosition = column.getFilterPosition();

      if (filterPosition.equals("bottom")) {
        encodeColumnHeaderContent(context, column, sortIcon);
        encodeFilter(context, table, column);
      } else if (filterPosition.equals("top")) {
        encodeFilter(context, table, column);
        encodeColumnHeaderContent(context, column, sortIcon);
      } else {
        throw new FacesException(
            filterPosition
                + " is an invalid option for filterPosition, valid values are 'bottom' or 'top'.");
      }
    } else {
      encodeColumnHeaderContent(context, column, sortIcon);
    }

    if (selectionMode != null && selectionMode.equalsIgnoreCase("multiple")) {
      encodeCheckbox(context, table, false, column.isDisabledSelection(), HTML.CHECKBOX_ALL_CLASS);
    }

    writer.endElement("th");
  }
  protected void encodeMarkup(FacesContext context, DataTable table) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    String clientId = table.getClientId(context);
    boolean scrollable = table.isScrollable();
    boolean hasPaginator = table.isPaginator();
    String style = table.getStyle();
    String paginatorPosition = table.getPaginatorPosition();

    // style class
    String containerClass =
        scrollable
            ? DataTable.CONTAINER_CLASS + " " + DataTable.SCROLLABLE_CONTAINER_CLASS
            : DataTable.CONTAINER_CLASS;
    containerClass =
        table.getStyleClass() != null
            ? containerClass + " " + table.getStyleClass()
            : containerClass;
    if (table.isResizableColumns())
      containerClass = containerClass + " " + DataTable.RESIZABLE_CONTAINER_CLASS;
    if (ComponentUtils.isRTL(context, table))
      containerClass = containerClass + " " + DataTable.RTL_CLASS;

    // default sort
    if (!table.isDefaultSorted() && table.getSortBy() != null && !table.isLazy()) {
      SortFeature sortFeature = (SortFeature) table.getFeature(DataTableFeatureKey.SORT);

      if (table.isMultiSort()) sortFeature.multiSort(context, table);
      else sortFeature.singleSort(context, table);

      table.setDefaultSorted();
    }

    if (hasPaginator) {
      table.calculateFirst();
    }

    writer.startElement("div", table);
    writer.writeAttribute("id", clientId, "id");
    writer.writeAttribute("class", containerClass, "styleClass");
    if (style != null) {
      writer.writeAttribute("style", style, "style");
    }

    encodeFacet(context, table, table.getHeader(), DataTable.HEADER_CLASS);

    if (hasPaginator && !paginatorPosition.equalsIgnoreCase("bottom")) {
      encodePaginatorMarkup(context, table, "top");
    }

    if (scrollable) {
      encodeScrollableTable(context, table);
    } else {
      encodeRegularTable(context, table);
    }

    if (hasPaginator && !paginatorPosition.equalsIgnoreCase("top")) {
      encodePaginatorMarkup(context, table, "bottom");
    }

    encodeFacet(context, table, table.getFooter(), DataTable.FOOTER_CLASS);

    if (table.isSelectionEnabled()) {
      encodeStateHolder(
          context,
          table,
          table.getClientId(context) + "_selection",
          table.getSelectedRowKeysAsString());
    }

    if (table.isDraggableColumns()) {
      encodeStateHolder(context, table, table.getClientId(context) + "_columnOrder", null);
    }

    if (scrollable) {
      encodeStateHolder(
          context, table, table.getClientId(context) + "_scrollState", table.getScrollState());
    }

    writer.endElement("div");
  }