Initial commit of Dark Canary channel handler.

The basic strategy here is to insert a downstream channel handler before the default channel handler. This
new handler will inspect the request to see if it is going to a mirrored host. If it is, it copies the request
with, modifies the target host, stores the request id, and then sends the new request to the io client.

We also install an upstream handler. This handler gets responses beofre the default channel handler. The new
handler checks to see if a response is for a mirrored request. If it is, it stops propagation of the response,
hence ensuring that the dark responses can never reach the production client.
Three main changes:

  1) Made zookeeper drive the configuration of mirrored hosts. We can now disable dark canaries completely
     by marking dark canary hosts unavailable in Zookeeper.
  2) The zookeeper service name that the dark canary handler connects to is part of the NetworkClientConfiguration
     and can be populated by existing means (through spring, etc.)
  3) Made the DarkCanaryChannelHandlers no-ops if no Zookeeper serviceName is configured.
Adding copyright notice to the DarkCanaryChannelHandler.scala file
Converted the DarkCanaryChannelHandler to be a class instead of an object. This way we have one handler, and
hence one ZooKeeperClusterClient per PartitionedNetworkClient.

The previous setup would not have worked if we had multiple PartionedNetworkClient objects in a single process:
they would all have shared the same zookeeper client, and only one of them would have got the correct dark
canary configurations.
Restore original version of ClusterIoClientComponent. There was no need to change it and the changes were
breaking some tests.
Implement Unit tests for the DarkCanaryChannelHandler and nested classes.
Version bump
Added comments describing the operation of the DarkCanaryChannelHandler. Also added copyright message to the
unit tests.
Reverting changes to ClientChannelHandler since they have become unnecessary with newer versions of the DarkCanaryChannelHandler
Address code review comments:

  1) Prefer Options over null.
  2) Prefer == over equals.
  3) Don't use explicit returns.
Address review board comments:

  1) Only initialize dark canaries and register handlers if a dark canary service name is defined.
  2) Made the dark canary client name suffix a variable, not a static string.
Cleanup resource leak in ChannelPool

Currently, we allow at most 5 inflight requests to a given host. If another request comes to the same host,
it is queued in the waitingWrites queue in the channel pool.

If the host is slow, the request will be timed out upstream and the request object will be cleaned in the
ClientChannelHandler, etc.

However, these requests are never cleaned from the waitingWrites queue in the ChannelPool. This patch
amends this state of afairs. Now each channel pool will have a cleaner thread which removes requests
which have been timed out and removed from the ClientChannelHandler.
Address code review comments:

  1) Define custom 'DarkCanaryException' type and use it.
  2) Replace !(x == y) with (x != y)
Clenup inconsistent vertical whitespaces
Merge pull request #50 from linkedin/dark-canary

Implementation of 'Dark Canary' functionality for Norbert