class ColumnTypeDetector {

  public ColumnType[] detectColumnTypes(Iterator<String[]> rows, ReadOptions options) {
    boolean useSampling = options.sample();

    // to hold the results
    List<ColumnType> columnTypes = new ArrayList<>();

    // to hold the data read from the file
    List<List<String>> columnData = new ArrayList<>();

    int rowCount = 0; // make sure we don't go over maxRows

    int nextRow = 0;
    while (rows.hasNext()) {
      String[] nextLine = rows.next();
      // initialize the arrays to hold the strings. we don't know how many we need until we read the
      // first row
      if (rowCount == 0) {
        for (int i = 0; i < nextLine.length; i++) {
          columnData.add(new ArrayList<>());
        }
      }
      int columnNumber = 0;
      if (rowCount == nextRow) {
        for (String field : nextLine) {
          columnData.get(columnNumber).add(field);
          columnNumber++;
        }
        if (useSampling) {
          nextRow = nextRow(nextRow);
        } else {
          nextRow = nextRowWithoutSampling(nextRow);
        }
      }
      rowCount++;
    }

    // now detect
    for (List<String> valuesList : columnData) {
      ColumnType detectedType = detectType(valuesList, options);
      if (detectedType.equals(StringColumnType.STRING)
          && rowCount > STRING_COLUMN_ROW_COUNT_CUTOFF) {
        HashSet<String> unique = new HashSet<>(valuesList);
        double uniquePct = unique.size() / (valuesList.size() * 1.0);
        if (uniquePct > STRING_COLUMN_CUTOFF) {
          detectedType = TEXT;
        }
      }
      columnTypes.add(detectedType);
    }
    return columnTypes.toArray(new ColumnType[0]);
  }

  public  ColumnTypeDetector(List<ColumnType> typeArray);

}