Store performance for issue #358

+ Tasks are now stored as individual keys.
+ Apps using the old storage format will be migrated on their first read if found.
+ Marathon performs some cleanup of orphaned tasks once after a reboot.
+ Added comprehensive unit tests for the TaskTracker module and refactored code slightly.
Hey @ssk2 
I tried to reproduce the problem, but was not able to.

The problem comes from the TaskTracker.shutdown method with these lines:
```scala
    apps.getOrElseUpdate(appName, fetchApp(appName)).shutdown = true
    if (apps(appName).tasks.isEmpty) remove(appName)
```
The getOrElseUpdate handles the case of a missing key.
The second line throws the exception, if there is no entry with this key.
Since this is a mutable map, we can not be sure, that the map has been changed in the meantime. (and this is probably the reason, why it is hard to reproduce). You have to handle this case. e.g. like this:

```scala
    val app = apps.getOrElseUpdate(appName, fetchApp(appName))
    app.shutdown = true
    if (app.tasks.isEmpty) remove(appName)
```