[FLINK-1293] Add support for out-of-place aggregations

This patch adds support for multiple aggregations on the same field and aggregations which change the output type, e.g., count and average.

It adds the following aggregation syntax to the Java API:

    // A string key and a long value
    DataSet<Tuple2<String, Long>> ds = ...

    // count all the elements
    DataSet<Tuple1<Long>> result = ds.aggregate(count()); 

    //  count elements in each group
    DataSet<Tuple2<String, Long>> result = ds.groupBy(0).aggregate(allKeys(), count()); 

    // same as above but explicitly state the returned key(s)
    DataSet<Tuple2<String, Long>> result = ds.groupBy(0).aggregate(key(0), count());

    // only return counts, drop keys
    DataSet<Tuple1<Long>> result = ds.groupBy(0).aggregate(count());

    // average reuses count and sum
    DataSet<Tuple4<String, Long, Long, Double>> result = 
        ds.groupBy(0).aggregate(allKeys(), count(), sum(1), average(1));

Five aggregation functions are supported: min, max, sum, count and average. Notice that count does not take a field reference in the example above.

Internally, the aggregation is implemented by the following operator chain:

    Input -> Map1 -> Reduce -> Map2 -> Output

- Map1 constructs an intermediate tuple on which the aggregation is performed. It's main task is to copy tuple fields that are used in multiple aggregation functions and initialize fields required for the internal implementation of aggregation functions. For example, average requires a field to count the tuples.

- Reduce performs the actual aggregation

- Map2 computes the final result of the aggregation function, e.g., computing the average from the sum and the count, and drops the fields used in groupings that are not requested in the output.

Average is implemented to reuse an existing sum and/or count function. In the last example above, the intermediate tuple contains only 3 fields: the key, a field to compute the sum, and a field to compute the count. The field holding the average is added after the Reduce operator in the Map2 operator.

Currently, only the Java API is implemented. My Scala knowledge is fairly limited, so it would be great if somebody else could pick that up.

Also, the result type of aggregate is simply &lt;T extends Tuple>. To support type inference at compile time, it is necessary to integrate the work by Chen (https://github.com/apache/incubator-flink/pull/194).
AggregationTest is a better name because the alternative API is no longer in the branch.

However, I'm not sure about the location of the test. It looks more like a unit test because it checks various correct call patterns and error conditions. However, for many tests it constructs a complete execution environment and consequently runs slow.

In addition it cannot be in the flink-java package because the execution environment is in flink-runtime which depends on flink-java and then you have a circular dependency.

I think the best place would be flink-tests but I don't want to have it run as an integration test.