### Question:
CompositeGenerator implements Generator<T> { @Override public T next() { List<I> generatedValues = newArrayList(); for (Generator<I> generator : stringGenerator) { generatedValues.add(generator.next()); } return aggregationFunction.apply(generatedValues); } CompositeGenerator(Function<List<I>, T> aggregationFunction, List<Generator<I>> generators); @Override T next();  }### Answer:
@Test public void shouldConcatenateGeneratedValues() { Generator<Object> stringGenerator = Generators.<Object>ofInstance("someString"); Generator<Object> integerGenerator = Generators.<Object>ofInstance(78); Function<List<Object>, String> aggregationFunction = new Function<List<Object>, String>() { @Nullable @Override public String apply(@Nullable List<Object> input) { return Joiner.on(",").join(input); } }; Generator<String> compositeGenerator = new CompositeGenerator<>(aggregationFunction, asList(stringGenerator, integerGenerator)); String generatedString = compositeGenerator.next(); assertThat(generatedString, is("someString,78")); }
@Test public void shouldCreateRichObject() { String someString = "someString"; Generator<Object> stringGenerator = Generators.<Object>ofInstance(someString); byte age = 25; Generator<Object> byteGenerator = Generators.<Object>ofInstance(age); Function<List<Object>, Person> aggregationFunction = new Function<List<Object>, Person>() { @Override public Person apply(List<Object> input) { return new Person(getFirst(input, null).toString(), (byte) getLast(input, null)); } }; Generator<Person> compositeGenerator = new CompositeGenerator<>(aggregationFunction, asList(stringGenerator, byteGenerator)); Person generatedString = compositeGenerator.next(); assertThat(generatedString, is(new Person(someString, age))); }