/**
   * Set the {@link BuildOutput}s that should be shown in this panel. A copy of the given collection
   * will be stored internally. If the collection is <code>null</code>, then an empty list will be
   * stored.
   *
   * @param buildOutputs The {@link BuildOutput}s
   */
  void setBuildOutputs(Collection<? extends BuildOutput> buildOutputs) {
    if (buildOutputs == null) {
      this.buildOutputs = Collections.emptyList();
    } else {
      this.buildOutputs = new ArrayList<BuildOutput>(buildOutputs);
    }

    projectsTableModel.setRowCount(0);
    for (BuildOutput buildOutput : buildOutputs) {
      String projectName = buildOutput.getProjectName();
      boolean skipped = buildOutput.isSkippedBuild();
      List<CompilerMessage> compilerWarnings = buildOutput.getCompilerWarnings();
      int numCompilerWarnings = compilerWarnings.size();
      List<CompilerMessage> compilerErrors = buildOutput.getCompilerErrors();
      int numCompilerErrors = compilerErrors.size();
      List<LinkerMessage> linkerWarnings = buildOutput.getLinkerWarnings();
      int numLinkerWarnings = linkerWarnings.size();
      List<LinkerMessage> linkerErrors = buildOutput.getLinkerErrors();
      int numLinkerErrors = linkerErrors.size();
      boolean hasIncludes = !buildOutput.getIncludes().isEmpty();

      projectsTableModel.addRow(
          new Object[] {
            projectName,
            skipped,
            numCompilerWarnings,
            numCompilerErrors,
            numLinkerWarnings,
            numLinkerErrors,
            hasIncludes
          });
    }
    JTables.adjustColumnWidths(projectsTable, Short.MAX_VALUE);
  }
  /**
   * Update the filter for the {@link #projectsTable}, depending on the state of the check boxes
   * that are associated with the {@link #hideSkippedBuildsAction}, {@link
   * #hideBuildsWithoutMessagesAction} and {@link #hideBuildsWithoutIncludesAction}
   */
  private void updateProjectsTableFilter() {
    RowFilter<TableModel, Object> isSkipped = booleanValueFilter(SKIPPED_COLUMN_INDEX);

    RowFilter<TableModel, Object> hasCompilerWarnings =
        RowFilter.numberFilter(ComparisonType.AFTER, 0, COMPILER_WARNINGS_COLUMN_INDEX);

    RowFilter<TableModel, Object> hasCompilerErrors =
        RowFilter.numberFilter(ComparisonType.AFTER, 0, COMPILER_ERRORS_COLUMN_INDEX);

    RowFilter<TableModel, Object> hasLinkerWarnings =
        RowFilter.numberFilter(ComparisonType.AFTER, 0, LINKER_WARNINGS_COLUMN_INDEX);

    RowFilter<TableModel, Object> hasLinkerErrors =
        RowFilter.numberFilter(ComparisonType.AFTER, 0, LINKER_ERRORS_COLUMN_INDEX);

    RowFilter<TableModel, Object> hasMessages =
        RowFilter.orFilter(
            Arrays.asList(
                hasCompilerWarnings, hasCompilerErrors,
                hasLinkerWarnings, hasLinkerErrors));

    RowFilter<TableModel, Object> hasIncludes = booleanValueFilter(INCLUDE_COLUMN_INDEX);

    RowFilter<TableModel, Object> r = trueFilter();
    if (isSelected(hideSkippedBuildsAction)) {
      r = RowFilter.andFilter(Arrays.asList(r, RowFilter.notFilter(isSkipped)));
    }
    if (isSelected(hideBuildsWithoutMessagesAction)) {
      r = RowFilter.andFilter(Arrays.asList(r, hasMessages));
    }
    if (isSelected(hideBuildsWithoutIncludesAction)) {
      r = RowFilter.andFilter(Arrays.asList(r, hasIncludes));
    }
    projectsTableRowSorter.setRowFilter(r);
    JTables.adjustColumnWidths(projectsTable, Short.MAX_VALUE);
  }