class CsvConverter implements Converter {

  @SuppressFBWarnings(value = "UC_USELESS_OBJECT", justification = "False positive with List.forEach")
  public String convertToCsv(Recording recording) {
    List<String> header = makeHeader(recording);
    int headerSize = header.size();
    CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader(header.toArray(new String[headerSize]));

    try (var writer = new StringWriter();
         var csvPrinter = new CSVPrinter(writer, csvFormat)) {
      var flattenedData = Converter.flatten(recording, not(Converter::isMetadata), windowSize.get());

      var rows = flattenedData.entrySet()
          .stream()
          .sorted(Comparator.comparingLong(Map.Entry::getKey))
          .map(e -> toRow(header, headerSize, e))
          .filter(Objects::nonNull)
          .collect(Collectors.toList());

      if (fillEmpty.get()) {
        fillEmptyCells(rows);
      }

      for (Object[] row : rows) {
        csvPrinter.printRecord(row);
      }

      return writer.toString();
    } catch (IOException e) {
      throw new IllegalStateException("Could not convert recording to CSV", e);
    }
  }

  @VisibleForTesting  CsvConverter(Preferences prefs);

}