class ElasticsearchJson {

    static void visitValueNodes( Aggregations aggregations, Consumer<Map<String, Object>> consumer ) {
        Objects.requireNonNull( aggregations, "aggregations" );
        Objects.requireNonNull( consumer, "consumer" );

        Map<RowKey, List<MultiValue>> rows = new LinkedHashMap<>();

        BiConsumer<RowKey, MultiValue> cons = ( r, v ) -> rows.computeIfAbsent( r, ignore -> new ArrayList<>() ).add( v );
        aggregations.forEach( a -> visitValueNodes( a, new ArrayList<>(), cons ) );
        rows.forEach( ( k, v ) -> {
            if ( v.stream().anyMatch( val -> val instanceof GroupValue ) ) {
                v.forEach( tuple -> {
                    Map<String, Object> groupRow = new LinkedHashMap<>( k.keys );
                    groupRow.put( tuple.getName(), tuple.value() );
                    consumer.accept( groupRow );
                } );
            } else {
                Map<String, Object> row = new LinkedHashMap<>( k.keys );
                v.forEach( val -> row.put( val.getName(), val.value() ) );
                consumer.accept( row );
            }
        } );
    }

    private  ElasticsearchJson();

}