protected void encodeRowExpansion(FacesContext context, DataTable table) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    Map<String, String> params = context.getExternalContext().getRequestParameterMap();
    int expandedRowIndex =
        Integer.parseInt(params.get(table.getClientId(context) + "_expandedRowIndex"));
    String rowIndexVar = table.getRowIndexVar();

    table.setRowIndex(expandedRowIndex);

    if (rowIndexVar != null) {
      context.getExternalContext().getRequestMap().put(rowIndexVar, expandedRowIndex);
    }

    writer.startElement("tr", null);
    writer.writeAttribute("style", "display:none", null);
    writer.writeAttribute(
        "class", DataTable.EXPANDED_ROW_CONTENT_CLASS + " ui-widget-content", null);

    writer.startElement("td", null);
    writer.writeAttribute("colspan", table.getColumnsCount(), null);

    table.getRowExpansion().encodeAll(context);

    writer.endElement("td");

    writer.endElement("tr");

    table.setRowIndex(-1);
  }
  protected void encodeScript(FacesContext context, DataTable table) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    String clientId = table.getClientId(context);
    String selectionMode = table.resolveSelectionMode();

    WidgetBuilder wb = getWidgetBuilder(context);
    wb.widget("DataTable", table.resolveWidgetVar(), clientId, true);

    // Pagination
    if (table.isPaginator()) {
      encodePaginatorConfig(context, table, wb);
    }

    // Selection
    wb.attr("selectionMode", selectionMode, null);

    // Filtering
    if (table.isFilteringEnabled()) {
      wb.attr("filter", true)
          .attr("filterEvent", table.getFilterEvent(), null)
          .attr("filterDelay", table.getFilterDelay(), Integer.MAX_VALUE);
    }

    // Row expansion
    if (table.getRowExpansion() != null) {
      wb.attr("expansion", true);
    }

    // Scrolling
    if (table.isScrollable()) {
      wb.attr("scrollable", true)
          .attr("liveScroll", table.isLiveScroll())
          .attr("scrollStep", table.getScrollRows())
          .attr("scrollLimit", table.getRowCount())
          .attr("scrollWidth", table.getScrollWidth(), null)
          .attr("scrollHeight", table.getScrollHeight(), null);
    }

    // Resizable/Draggable Columns
    wb.attr("resizableColumns", table.isResizableColumns(), false)
        .attr("liveResize", table.isLiveResize(), false)
        .attr("draggableColumns", table.isDraggableColumns(), false);

    // Editing
    if (table.isEditable()) {
      wb.attr("editable", true)
          .attr("editMode", table.getEditMode())
          .attr("cellSeparator", table.getCellSeparator(), null);
    }

    // MultiColumn Sorting
    if (table.isMultiSort()) {
      wb.attr("multiSort", true);
    }

    // Behaviors
    encodeClientBehaviors(context, table, wb);

    startScript(writer, clientId);
    writer.write(wb.build());
    endScript(writer);
  }