private void constructHeaderRow(Sink sink, List issueList, ResourceBundle bundle) {
    if (issueList == null) {
      return;
    }

    sink.table();

    sink.tableRow();

    for (int columnIndex = 0; columnIndex < columns.length; columnIndex++) {
      switch (columns[columnIndex]) {
        case IssuesReportHelper.COLUMN_ASSIGNEE:
          sinkHeader(sink, bundle.getString("report.issues.label.assignee"));
          break;

        case IssuesReportHelper.COLUMN_COMPONENT:
          sinkHeader(sink, bundle.getString("report.issues.label.component"));
          break;

        case IssuesReportHelper.COLUMN_CREATED:
          sinkHeader(sink, bundle.getString("report.issues.label.created"));
          break;

        case IssuesReportHelper.COLUMN_FIX_VERSION:
          sinkHeader(sink, bundle.getString("report.issues.label.fixVersion"));
          break;

        case IssuesReportHelper.COLUMN_ID:
          sinkHeader(sink, bundle.getString("report.issues.label.id"));
          break;

        case IssuesReportHelper.COLUMN_KEY:
          sinkHeader(sink, bundle.getString("report.issues.label.key"));
          break;

        case IssuesReportHelper.COLUMN_PRIORITY:
          sinkHeader(sink, bundle.getString("report.issues.label.priority"));
          break;

        case IssuesReportHelper.COLUMN_REPORTER:
          sinkHeader(sink, bundle.getString("report.issues.label.reporter"));
          break;

        case IssuesReportHelper.COLUMN_RESOLUTION:
          sinkHeader(sink, bundle.getString("report.issues.label.resolution"));
          break;

        case IssuesReportHelper.COLUMN_STATUS:
          sinkHeader(sink, bundle.getString("report.issues.label.status"));
          break;

        case IssuesReportHelper.COLUMN_SUMMARY:
          sinkHeader(sink, bundle.getString("report.issues.label.summary"));
          break;

        case IssuesReportHelper.COLUMN_TYPE:
          sinkHeader(sink, bundle.getString("report.issues.label.type"));
          break;

        case IssuesReportHelper.COLUMN_UPDATED:
          sinkHeader(sink, bundle.getString("report.issues.label.updated"));
          break;

        case IssuesReportHelper.COLUMN_VERSION:
          sinkHeader(sink, bundle.getString("report.issues.label.version"));
          break;

        default:
          // Do not add a header for this column
          break;
      }
    }

    sink.tableRow_();
  }
  private void constructDetailRows(
      Sink sink, List issueList, ResourceBundle bundle, Locale locale) {
    if (issueList == null) {
      return;
    }

    for (int idx = 0; idx < issueList.size(); idx++) {
      // Use a DateFormat based on the Locale
      DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);

      Issue issue = (Issue) issueList.get(idx);

      sink.tableRow();

      for (int columnIndex = 0; columnIndex < columns.length; columnIndex++) {
        switch (columns[columnIndex]) {
          case IssuesReportHelper.COLUMN_ASSIGNEE:
            sinkCell(sink, issue.getAssignee());
            break;

          case IssuesReportHelper.COLUMN_COMPONENT:
            sinkCell(sink, IssuesReportHelper.printValues(issue.getComponents()));
            break;

          case IssuesReportHelper.COLUMN_CREATED:
            String created = NOT_AVAILABLE;
            if (issue.getCreated() != null) {
              created = df.format(issue.getCreated());
            }
            sinkCell(sink, created);
            break;

          case IssuesReportHelper.COLUMN_FIX_VERSION:
            sinkCell(sink, IssuesReportHelper.printValues(issue.getFixVersions()));
            break;

          case IssuesReportHelper.COLUMN_ID:
            sink.tableCell();
            sink.link(issue.getLink());
            sink.text(issue.getId());
            sink.link_();
            sink.tableCell_();
            break;

          case IssuesReportHelper.COLUMN_KEY:
            sink.tableCell();
            sink.link(issue.getLink());
            sink.text(issue.getKey());
            sink.link_();
            sink.tableCell_();
            break;

          case IssuesReportHelper.COLUMN_PRIORITY:
            sinkCell(sink, issue.getPriority());
            break;

          case IssuesReportHelper.COLUMN_REPORTER:
            sinkCell(sink, issue.getReporter());
            break;

          case IssuesReportHelper.COLUMN_RESOLUTION:
            sinkCell(sink, issue.getResolution());
            break;

          case IssuesReportHelper.COLUMN_STATUS:
            sinkCell(sink, issue.getStatus());
            break;

          case IssuesReportHelper.COLUMN_SUMMARY:
            sinkCell(sink, issue.getSummary());
            break;

          case IssuesReportHelper.COLUMN_TYPE:
            sinkCell(sink, issue.getType());
            break;

          case IssuesReportHelper.COLUMN_UPDATED:
            String updated = NOT_AVAILABLE;
            if (issue.getUpdated() != null) {
              updated = df.format(issue.getUpdated());
            }
            sinkCell(sink, updated);
            break;

          case IssuesReportHelper.COLUMN_VERSION:
            sinkCell(sink, issue.getVersion());
            break;

          default:
            // Do not add this column
            break;
        }
      }

      sink.tableRow_();
    }

    sink.table_();
  }