class DataFrameBuilder {

    public <T> DataFrame foldIterableByRow(Iterable<T> iterable) {

        int width = columnsIndex.size();
        if (width == 0) {
            throw new IllegalArgumentException("Empty columns");
        }

        int heightEstimate = (iterable instanceof Collection) ? ((Collection) iterable).size() : 10;

        Accumulator<Object>[] columnBuilders = new Accumulator[width];
        for (int i = 0; i < width; i++) {
            columnBuilders[i] = new ObjectAccumulator<>(heightEstimate);
        }

        int p = 0;
        for (Object o : iterable) {
            columnBuilders[p % width].add(o);
            p++;
        }

        // fill the last row to the end
        int pl = p % width;
        if (pl > 0) {
            for (; pl < width; pl++) {
                columnBuilders[pl].add(null);
            }
        }

        Series<?>[] series = new Series[columnBuilders.length];
        for (int i = 0; i < columnBuilders.length; i++) {
            series[i] = columnBuilders[i].toSeries();
        }

        return new ColumnDataFrame(columnsIndex, series);
    }

    protected  DataFrameBuilder(Index columnsIndex);

}