Balancing httpclient

HttpClient and AsyncHttpClient implementations which take relative URLs, implement discovery lookup, and retry requests.

How one uses it:

A user of BalancingHttpClient uses DiscoveryBinder to bind it to a discovery
service type:

```java
    DiscoveryBinder.bindHttpClient(serviceType("storage"), StorageClient.class)
        .withFilter(SomeFilter.class)
        .withTracing();
```

The resulting HttpClient can be injected in the normal way:

```java
    @Inject
    StorageUser(@StorageClient HttpClient httpClient)
```

The resulting HttpClient differs in that it that the Request URI must be
relative:

```java
    httpClient.execute(prepareGet().setUri(URI.create("v1/content/foo")).build(),
            new StorageResponseHandler());
```

The BalancingHttpClient will send the request to some base URI obtained from
the discovery service for the ServiceType that the HttpClient was bound to and
for the pool obtained from configuration. If there are no available instances,
it will throw a ServiceUnavailableException.

The BalancingHttpClient will retry the request, up to a configurable number of
total attempts, if the underlying HttpClient reports either an exception
through ResponseHandler.handleException() or a response with a status code of
408, 500, 502, 503, or 504.

The ResponseHandler given to the BalancingHttpClient will be called at most
once. The BalancingHttpClient won't retry if the caller's
ResponseHandler.handle() method throws an exception.

The Request and its BodyGenerator may be required to produce their contents
many times.

A user may alternatively bind an AsyncHttpClient, in which case they get a
BalancingAsyncHttpClient.


Internals:

The BalancingHttpClient works by using an underlying traditional HttpClient.
It resolves a base URI obtained from discovery against the caller's relative
URI when passing the client Request to the underlying HttpClient. It
(sometimes) wraps the caller's ResponseHandler in its own ResponseHandler
which intercepts responses that are retryable.

As there can be multiple BalancingHttpClient instances, each bound to a
different ServiceType, the underlying HttpClient needs to be bound with
a private binder in order to solve the resulting "robot legs" problem. Getting
private binding of an HttpClient to work has required several changes to
Platform.


HttpServiceBalancer:

In the future, the BalancingHttpClient will remember which URIs have high
failure rates and send fewer requests to them. This memory will be implemented
in a newly created HttpServiceBalancer class. An HttpServiceBalancer is
similar to an HttpServiceSelector in that it is a source of URI objects,
but it uses a newly created HttpServiceAttempt interface to receive
information about which attempts failed and which succeeded. The
HttpServiceAttempt interface also allows the selection of the next URI to try
to be delayed until after previous attempts have failed.

In order for HttpServiceBalancer to get its list of URIs from the discovery
client, the periodic query code that was previously in CachingServiceSelector
has been extracted into a new ServiceDescriptorsUpdater class. The
ServiceDescriptorsUpdater class delivers its updated lists of
ServiceDescripors to the ServiceDescriptorsUpdateable interface, which is
implemented by both CachingServiceSelector and HttpServiceBalancerImpl.
Additionally, the ServiceInventory uses the ServiceDescriptorsUpdateable
interface to deliver a list of discovery server URIs to a
HttpServiceBalancerImpl used by the discovery client itself.