Rculbertson/tombstone rebase

With this PR, we no longer use tombstones. Instead when a job is removed, the master will delete the job from zookeeper. To protect against the case where operational error causes zookeeper to lose all data, or we aim an agent at the wrong zookeeper cluster, we check for the existence of a cluster ID node. If this node is not present, the zookeeper client will throw an exception, and the agent will not sync down the latest jobs.

Extracting this to a method that looks like what follows makes the code a bit cleaner and clarifies the intent.
```java
private List<String> getChildren() {
  final Stat childrenStat = new Stat();
  while (true) {
    final List<String> possibleChildren = curator
        .getChildren()
        .storingStatIn(childrenStat)
        .usingWatcher(childrenWatcher)
        .forPath(path);

    if (clusterId == null) {
      return possibleChildren;
    }

    // check that cluster node is right
    try {
      curator.inTransaction()
          .check().forPath(String.format("/config/id/%s", clusterId)).and()
          .check().withVersion(childrenStat.getVersion()).forPath(path).and()
          .commit();
    } catch (KeeperException.BadVersionException e) {
      // Jobs have somehow changed while we were creating the transaction, retry.

      // is some form of sleep or backoff appropriate here?
      continue;
    }
    return possibleChildren;
  }
}
```

I'm guessing that @Kobolog wrote this.  Presuming so, you might want to read [this](https://drew.thecsillags.com/refactoring-flow-control-and-conditionals/) on ways to make the flow control bits a bit clearer.  This way you can get rid of state flags (here `children==null`) and reduce some redundant code.