Making Zookeeper integration code more readable.

I've been re-visiting the zookeeper code. Initially I was looking into it because it wasn't working (it turned out java version compatibility issue), but I got better understanding of the code and wanted to make it more organized.

* Making more variables into `final` so that the state modification is more controlled.
* Adding comments in various places, especially regarding the lock states.
* Adding zookeeper bootstrapping to the test suite, and moving the test out of the integration test (in fact, this test was blacklisted and was never executed).
* Reducing the usage of the mockito whitebox.
* Reducing the amount of shared states, by pulling the scavanger state out of the member variable and storing it within the function scope.
* Removing the usage of `java.util.Timer`.
* Separating out the zookeeper connection wait outside the constructor - that makes the tests more reliable, since having the lock managers in disconnected state is most likely bad.
One of the deficiencies of this approach [that has always existed] is that the threshold at which we stop acquiring locks is 50% (hardcoded) of the number of shards owned, instead of some configured value that probably indicates the how shard ownership is duplicated across rollup nodes. E.g.: would be 34% if each shard were assigned to three nodes.

The main deficiency is that it could lead to starvation where one node owned, say 50% and other nodes (assuming more than one) own some fraction of the remaining 50%.

FYI, the design goal we were going after here was loose coordination based on observing other nodes. The alternative would have been some kind of master that assigns ownership to shards based on several factors (load, latency, etc.).