[SPARK-2044] Pluggable interface for shuffles

This is a first cut at moving shuffle logic behind a pluggable interface, as described at https://issues.apache.org/jira/browse/SPARK-2044, to let us more easily experiment with new shuffle implementations. It moves the existing shuffle code to a class HashShuffleManager behind a general ShuffleManager interface.

Two things are still missing to make this complete:
* MapOutputTracker needs to be hidden behind the ShuffleManager interface; this will also require adding methods to ShuffleManager that will let the DAGScheduler interact with it as it does with the MapOutputTracker today
* The code to do map-sides and reduce-side combine in ShuffledRDD, PairRDDFunctions, etc needs to be moved into the ShuffleManager's readers and writers

However, some of these may also be done later after we merge the current interface.
```
scala> var serializer: Option[java.lang.Integer] = null
serializer: Option[Integer] = null

scala> serializer = Some(1)
serializer: Option[Integer] = Some(1)

scala> serializer.get
res0: Integer = 1

scala> serializer = Some(null)
serializer: Option[Integer] = Some(null)

scala> serializer.get
res1: Integer = null

scala> serializer.isDefined
res2: Boolean = true

scala> serializer = Option(null)
serializer: Option[Integer] = None

scala> serializer.isDefined
res3: Boolean = false
```