Expose aplication ID in ApplicationStart event, use it in history server.

This change exposes the application ID generated by the Spark Master, Mesos or Yarn
via the SparkListenerApplicationStart event. It then uses that information to expose the
application via its ID in the history server, instead of using the internal directory name
generated by the event logger as an application id. This allows someone who knows
the application ID to easily figure out the URL for the application's entry in the HS, aside
from looking better.

In Yarn mode, this is used to generate a direct link from the RM application list to the
Spark history server entry (thus providing a fix for SPARK-2150).

Note this sort of assumes that the different managers will generate app ids that are
sufficiently different from each other that clashes will not occur.
Also I find this code path pretty convoluted for what it's doing. Can you simplify this by doing something that looks more like a merge sort (semi-pseudocode)
```
val newInfos = new PeekingIterator(logInfo.iterator)
val oldInfos = new PeekingIterator(appList.values.iterator)
while (newInfos.hasNext && oldInfos.hasNext) {
  val newInfo = newInfos.peek
  val oldInfo = oldInfos.peek
  if (newInfo.endTime < oldInfo.endTime) {
    newMap.putIfAbsent(oldInfo.appId, oldInfos.next)
  } else {
    newMap.putIfAbsent(newInfo.appId, newInfos.next)
  }
}

oldInfos.foreach { info => newMap.putIfAbsent(info.appId, info) }
newInfos.foreach { info => newMap.putIfAbsent(info.appId, info) }
```
Note that you can also do this without the peeking iterator, but it's just easier to read with it.