@Override
 protected String[][] getRawDataColumnHeaders() {
   Collection<WebViewGridColumn> columns = getGridStructure().getColumns();
   int additionalColumns = getAdditionalCsvColumnCount();
   int columnCount = columns.size() + additionalColumns;
   String[] header1 = new String[columnCount];
   String[] header2 = new String[columnCount];
   supplementCsvColumnHeaders(header1);
   int offset = getCsvDataColumnOffset();
   for (WebViewGridColumn column : columns) {
     header1[offset + column.getId()] = column.getHeader();
     header2[offset + column.getId()] = column.getDescription();
   }
   return new String[][] {header1, header2};
 }
  private Map<String, Object> getJsonColumnStructure(WebViewGridColumn column) {
    Map<String, Object> detailsToSend = new HashMap<String, Object>();
    long colId = column.getId();
    detailsToSend.put("colId", colId);
    detailsToSend.put("header", column.getHeader());
    detailsToSend.put("description", column.getValueName() + ":\n" + column.getDescription());
    detailsToSend.put("nullValue", _nullCellValue);

    String resultType = getConverterCache().getKnownResultTypeName(column.getValueName());
    if (resultType != null) {
      column.setTypeKnown(true);
      detailsToSend.put("dataType", resultType);

      // Hack - the client should decide which columns it requires history for, taking into account
      // the capabilities of
      // the renderer.
      if (resultType.equals("DOUBLE")) {
        addHistoryOutput(column.getId());
      }
    }
    return detailsToSend;
  }