CDK-634: Add Dataset creation to MR and Crunch.

This adds an option to set a descriptor for the output URI, which is
used to create a Dataset if one doesn't already exist. For Datasets
that use the MergeOutputCommitter, the final Dataset is created in the
commitJob method and the NullOutputCommitter creates the dataset in the
setupJob method because tasks write directly to it.

This adds methods to store and retrieve a descriptor in a Configuration
to DescriptorUtil. These methods take a context String that is used to
build property names, so multiple descriptors can be stored in the same
Configuration.

Because the Descriptor can be stored in the Job Configuration, this no
longer relies on the job Dataset to serialize the descriptor to task
attempts. Task attemps no longer load the job Dataset to create the task
attempt Datasets.
The merge committer creates the dataset only in the commit phase of the job. That way, if the job fails there is no change to the repository. Otherwise, a failed job would prevent a re-run from completing because the dataset already exists (if using the default write mode rather than append or overwrite).