static ColumnSchema calculateColumnSchema(OptionalInt screenWidth,
                                              List<String> entries) {
        if (!screenWidth.isPresent()) {
            return new ColumnSchema(1, entries.size());
        }
        int maxColumns = screenWidth.getAsInt() / 4;
        if (maxColumns <= 1) {
            return new ColumnSchema(1, entries.size());
        }
        ColumnSchema[] schemas = new ColumnSchema[maxColumns];
        for (int numColumns = 1; numColumns <= maxColumns; numColumns++) {
            schemas[numColumns - 1] = new ColumnSchema(numColumns,
                (entries.size() + numColumns - 1) / numColumns);
        }
        for (int i = 0; i < entries.size(); i++) {
            String entry = entries.get(i);
            for (ColumnSchema schema : schemas) {
                schema.process(i, entry);
            }
        }
        for (int s = schemas.length - 1; s > 0; s--) {
            ColumnSchema schema = schemas[s];
            if (schema.columnWidths[schema.columnWidths.length - 1] != 0 &&
                    schema.totalWidth() <= screenWidth.getAsInt()) {
                return schema;
            }
        }
        return schemas[0];
    }
@Test
    public void testCalculateColumnSchema() {
        assertEquals(new ColumnSchema(1, 3),
            LsCommandHandler.calculateColumnSchema(OptionalInt.empty(),
                Arrays.asList("abc", "def", "ghi")));
        assertEquals(new ColumnSchema(1, 2),
            LsCommandHandler.calculateColumnSchema(OptionalInt.of(0),
                Arrays.asList("abc", "def")));
        assertEquals(new ColumnSchema(3, 1).setColumnWidths(3, 8, 6),
            LsCommandHandler.calculateColumnSchema(OptionalInt.of(80),
                Arrays.asList("a", "abcdef", "beta")));
        assertEquals(new ColumnSchema(2, 3).setColumnWidths(10, 7),
            LsCommandHandler.calculateColumnSchema(OptionalInt.of(18),
                Arrays.asList("alphabet", "beta", "gamma", "theta", "zeta")));
    }