gt:             if (isGroupField(field)) {
context: package autotest.tko;
  
  import autotest.common.Utils;
  import autotest.common.CustomHistory.HistoryToken;
  import autotest.common.table.DataTable;
  import autotest.common.table.DynamicTable;
  import autotest.common.table.RpcDataSource;
  import autotest.common.table.SelectionManager;
  import autotest.common.table.SimpleFilter;
  import autotest.common.table.TableDecorator;
  import autotest.common.table.DataSource.SortDirection;
  import autotest.common.table.DataSource.SortSpec;
  import autotest.common.table.DataTable.TableWidgetFactory;
  import autotest.common.table.DynamicTable.DynamicTableListener;
  import autotest.common.ui.ContextMenu;
  import autotest.common.ui.DoubleListSelector;
  import autotest.common.ui.MultiListSelectPresenter;
  import autotest.common.ui.NotifyManager;
  import autotest.common.ui.MultiListSelectPresenter.Item;
  import autotest.common.ui.TableActionsPanel.TableActionsWithExportCsvListener;
  import autotest.tko.CommonPanel.CommonPanelListener;
  
  import com.google.gwt.event.dom.client.ClickEvent;
  import com.google.gwt.event.dom.client.ClickHandler;
  import com.google.gwt.json.client.JSONArray;
  import com.google.gwt.json.client.JSONObject;
  import com.google.gwt.user.client.Command;
  import com.google.gwt.user.client.Event;
  import com.google.gwt.user.client.History;
  import com.google.gwt.user.client.ui.Button;
  import com.google.gwt.user.client.ui.CheckBox;
  import com.google.gwt.user.client.ui.HTML;
  import com.google.gwt.user.client.ui.Panel;
  import com.google.gwt.user.client.ui.SimplePanel;
  import com.google.gwt.user.client.ui.VerticalPanel;
  import com.google.gwt.user.client.ui.Widget;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.List;
  import java.util.ListIterator;
  import java.util.Map;
  
  public class TableView extends ConditionTabView
                         implements DynamicTableListener, TableActionsWithExportCsvListener,
                                    ClickHandler, TableWidgetFactory, CommonPanelListener,
                                    MultiListSelectPresenter.GeneratorHandler {
      private static final int ROWS_PER_PAGE = 30;
      private static final String COUNT_NAME = "Count in group";
      private static final String STATUS_COUNTS_NAME = "Test pass rate";
      private static final String[] DEFAULT_COLUMNS =
          {"Test index", "Test name", "Job tag", "Hostname", "Status"};
      private static final String[] TRIAGE_GROUP_COLUMNS =
          {"Test name", "Status", COUNT_NAME, "Reason"};
      private static final String[] PASS_RATE_GROUP_COLUMNS =
          {"Hostname", STATUS_COUNTS_NAME};
      private static final SortSpec[] TRIAGE_SORT_SPECS = {
          new SortSpec("test_name", SortDirection.ASCENDING),
          new SortSpec("status", SortDirection.ASCENDING),
          new SortSpec("reason", SortDirection.ASCENDING),
      };
  
      private static enum GroupingType {NO_GROUPING, TEST_GROUPING, STATUS_COUNTS}
  
      /**
       * HeaderField representing a grouped count of some kind.
       */
      private static class GroupCountField extends HeaderField {
          public GroupCountField(String name, String sqlName) {
              super(name, sqlName);
          }
  
          @Override
          public Item getItem() {
              return Item.createGeneratedItem(getName(), getSqlName());
          }
  
          @Override
          public String getSqlCondition(String value) {
              throw new UnsupportedOperationException();
          }
  
          @Override
          public boolean isUserSelectable() {
              return false;
          }
      }
  
      private GroupCountField groupCountField =
          new GroupCountField(COUNT_NAME, TestGroupDataSource.GROUP_COUNT_FIELD);
      private GroupCountField statusCountsField =
          new GroupCountField(STATUS_COUNTS_NAME, DataTable.WIDGET_COLUMN);
  
      private TestSelectionListener listener;
  
      private DynamicTable table;
      private TableDecorator tableDecorator;
      private SelectionManager selectionManager;
      private SimpleFilter sqlConditionFilter = new SimpleFilter();
      private RpcDataSource testDataSource = new TestViewDataSource();
      private TestGroupDataSource groupDataSource = TestGroupDataSource.getTestGroupDataSource();
  
      private HeaderFieldCollection headerFields = commonPanel.getHeaderFields();
      private HeaderSelect columnSelect = new HeaderSelect(headerFields, new HeaderSelect.State());
  
      private DoubleListSelector columnSelectDisplay = new DoubleListSelector();
      private CheckBox groupCheckbox = new CheckBox("Group by these columns and show counts");
      private CheckBox statusGroupCheckbox =
          new CheckBox("Group by these columns and show pass rates");
      private Button queryButton = new Button("Query");
      private Panel tablePanel = new SimplePanel();
  
      private List<SortSpec> tableSorts = new ArrayList<SortSpec>();
  
      public enum TableViewConfig {
          DEFAULT, PASS_RATE, TRIAGE
      }
  
      public static interface TableSwitchListener extends TestSelectionListener {
          public void onSwitchToTable(TableViewConfig config);
      }
  
      public TableView(TestSelectionListener listener) {
          this.listener = listener;
          commonPanel.addListener(this);
          columnSelect.setGeneratorHandler(this);
          columnSelect.bindDisplay(columnSelectDisplay);
      }
  
      @Override
      public String getElementId() {
          return "table_view";
      }
  
      @Override
      public void initialize() {
          super.initialize();
  
          headerFields.add(groupCountField);
          headerFields.add(statusCountsField);
  
          selectColumnsByName(DEFAULT_COLUMNS);
          updateViewFromState();
  
          queryButton.addClickHandler(this);
          groupCheckbox.addClickHandler(this);
          statusGroupCheckbox.addClickHandler(this);
  
          Panel columnPanel = new VerticalPanel();
          columnPanel.add(columnSelectDisplay);
          columnPanel.add(groupCheckbox);
          columnPanel.add(statusGroupCheckbox);
  
          addWidget(columnPanel, "table_column_select");
          addWidget(queryButton, "table_query_controls");
          addWidget(tablePanel, "table_table");
      }
  
      private void selectColumnsByName(String[] columnNames) {
          List<HeaderField> fields = new ArrayList<HeaderField>();
          for (String name : columnNames) {
              fields.add(headerFields.getFieldByName(name));
          }
          columnSelect.setSelectedItems(fields);
          cleanupSortsForNewColumns();
      }
  
      public void setupDefaultView() {
          tableSorts.clear();
          selectColumnsByName(DEFAULT_COLUMNS);
          updateViewFromState();
      }
  
      public void setupJobTriage() {
          selectColumnsByName(TRIAGE_GROUP_COLUMNS);
          // need to copy it so we can mutate it
          tableSorts = new ArrayList<SortSpec>(Arrays.asList(TRIAGE_SORT_SPECS));
          updateViewFromState();
      }
  
      public void setupPassRate() {
          tableSorts.clear();
          selectColumnsByName(PASS_RATE_GROUP_COLUMNS);
          updateViewFromState();
      }
  
      private void createTable() {
          String[][] columns = buildColumnSpecs();
  
          table = new DynamicTable(columns, getDataSource());
          table.addFilter(sqlConditionFilter);
          table.setRowsPerPage(ROWS_PER_PAGE);
          table.makeClientSortable();
          table.setClickable(true);
          table.sinkRightClickEvents();
          table.addListener(this);
          table.setWidgetFactory(this);
          restoreTableSorting();
  
          tableDecorator = new TableDecorator(table);
          tableDecorator.addPaginators();
          selectionManager = tableDecorator.addSelectionManager(false);
          tableDecorator.addTableActionsWithExportCsvListener(this);
          tablePanel.clear();
          tablePanel.add(tableDecorator);
  
          selectionManager = new SelectionManager(table, false);
      }
  
      private String[][] buildColumnSpecs() {
          int numColumns = savedColumns().size();
          String[][] columns = new String[numColumns][2];
          int i = 0;
          for (HeaderField field : savedColumns()) {
              columns[i][0] = field.getSqlName();
              columns[i][1] = field.getName();
              i++;
          }
          return columns;
      }
  
      private List<HeaderField> savedColumns() {
          return columnSelect.getSelectedItems();
      }
  
      private RpcDataSource getDataSource() {
          GroupingType groupingType = getActiveGrouping();
          if (groupingType == GroupingType.NO_GROUPING) {
              return testDataSource;
          } else if (groupingType == GroupingType.TEST_GROUPING) {
              groupDataSource = TestGroupDataSource.getTestGroupDataSource();
          } else {
              groupDataSource = TestGroupDataSource.getStatusCountDataSource();
          }
  
          updateGroupColumns();
          return groupDataSource;
      }
  
      private void updateStateFromView() {
          commonPanel.updateStateFromView();
          columnSelect.updateStateFromView();
      }
  
      private void updateViewFromState() {
          commonPanel.updateViewFromState();
          columnSelect.updateViewFromState();
      }
  
      private void updateGroupColumns() {
          List<String> groupFields = new ArrayList<String>();
          for (HeaderField field : savedColumns()) {
              if (!isGroupField(field)) {
                  groupFields.add(field.getSqlName());
              }
          }
  
          groupDataSource.setGroupColumns(groupFields.toArray(new String[0]));
      }
  
      private boolean isGroupField(HeaderField field) {
          return field instanceof GroupCountField;
      }
  
      private void saveTableSorting() {
          if (table != null) {
              // we need our own copy so we can modify it later
              tableSorts = new ArrayList<SortSpec>(table.getSortSpecs());
          }
      }
  
      private void restoreTableSorting() {
          for (ListIterator<SortSpec> i = tableSorts.listIterator(tableSorts.size());
               i.hasPrevious();) {
              SortSpec sortSpec = i.previous();
              table.sortOnColumn(sortSpec.getField(), sortSpec.getDirection());
          }
      }
  
      private void cleanupSortsForNewColumns() {
          // remove sorts on columns that we no longer have
          for (Iterator<SortSpec> i = tableSorts.iterator(); i.hasNext();) {
              String attribute = i.next().getField();
              if (!isAttributeSelected(attribute)) {
                  i.remove();
              }
          }
  
          if (tableSorts.isEmpty()) {
              // default to sorting on the first column
              HeaderField field = savedColumns().iterator().next();
              SortSpec sortSpec = new SortSpec(field.getSqlName(), SortDirection.ASCENDING);
              tableSorts = new ArrayList<SortSpec>();
              tableSorts.add(sortSpec);
          }
      }
  
      private boolean isAttributeSelected(String attribute) {
          for (HeaderField field : savedColumns()) {
              if (field.getSqlName().equals(attribute)) {
                  return true;
              }
          }
          return false;
      }
  
      @Override
      public void refresh() {
          createTable();
          JSONObject condition = commonPanel.getConditionArgs();
          sqlConditionFilter.setAllParameters(condition);
          table.refresh();
      }
  
      @Override
      public void doQuery() {
          if (savedColumns().isEmpty()) {
              NotifyManager.getInstance().showError("You must select columns");
              return;
          }
          updateStateFromView();
          refresh();
      }
  
      @Override
      public void onRowClicked(int rowIndex, JSONObject row, boolean isRightClick) {
          Event event = Event.getCurrentEvent();
          TestSet testSet = getTestSet(row);
          if (isRightClick) {
              if (selectionManager.getSelectedObjects().size() > 0) {
                  testSet = getTestSet(selectionManager.getSelectedObjects());
              }
              ContextMenu menu = getContextMenu(testSet);
              menu.showAtWindow(event.getClientX(), event.getClientY());
              return;
          }
  
          if (isSelectEvent(event)) {
              selectionManager.toggleSelected(row);
              return;
          }
  
          HistoryToken historyToken;
          if (isAnyGroupingEnabled()) {
              historyToken = getDrilldownHistoryToken(testSet);
          } else {
              historyToken = listener.getSelectTestHistoryToken(testSet.getTestIndex());
          }
          openHistoryToken(historyToken);
      }
  
      private ContextMenu getContextMenu(final TestSet testSet) {
          TestContextMenu menu = new TestContextMenu(testSet, listener);
  
          if (!menu.addViewDetailsIfSingleTest() && isAnyGroupingEnabled()) {
              menu.addItem("Drill down", new Command() {
                  public void execute() {
                      doDrilldown(testSet);
                  }
              });
          }
  
          menu.addLabelItems();
          return menu;
      }
  
      private HistoryToken getDrilldownHistoryToken(TestSet testSet) {
          saveHistoryState();
          commonPanel.refineCondition(testSet);
          selectColumnsByName(DEFAULT_COLUMNS);
          HistoryToken historyToken = getHistoryArguments();
          restoreHistoryState();
          return historyToken;
      }
  
      private void doDrilldown(TestSet testSet) {
          History.newItem(getDrilldownHistoryToken(testSet).toString());
      }
  
      private TestSet getTestSet(JSONObject row) {
          if (!isAnyGroupingEnabled()) {
              return new SingleTestSet((int) row.get("test_idx").isNumber().doubleValue());
          }
  
          ConditionTestSet testSet = new ConditionTestSet(commonPanel.getConditionArgs());
          for (HeaderField field : savedColumns()) {
  