CDK-488: Add TaskUtil.partition.

This utility method regroups a PCollection using a specified number of
reducers. This can be used to control the number of files created by a
copy job. The number of reducers is approximately the number of files
produced, but at least one file per partition will be created.

This is implemented in two ways. If the dataset is partitioned, the
entities are grouped by partition key so that each partition is handled
by one reducer and the number of files created is minimized. If the
dataset is not partitioned, this will perform the regroup operation
using the entities themselves as keys to produce the right number of
files, one per reduce task.
The test doesn't actually test that the expected number of files were created in the target dataset. This test should check that there is one, testCopyWithNumWriters should check there are three, and testPartitionedCopyWithNumWriters should check there are two (the number of partitions).

I noticed that the test is using MemPipeline - we should switch it to run in parallel to test this correctly.