private NodeCache makeNodeCache(final ServiceInstance<T> instance) {
    if (!watchInstances) {
      return null;
    }

    final NodeCache nodeCache =
        new NodeCache(client, pathForInstance(instance.getName(), instance.getId()));
    try {
      nodeCache.start(true);
    } catch (Exception e) {
      log.error("Could not start node cache for: " + instance, e);
    }
    NodeCacheListener listener =
        new NodeCacheListener() {
          @Override
          public void nodeChanged() throws Exception {
            if (nodeCache.getCurrentData() != null) {
              ServiceInstance<T> newInstance =
                  serializer.deserialize(nodeCache.getCurrentData().getData());
              Entry<T> entry = services.get(newInstance.getId());
              if (entry != null) {
                synchronized (entry) {
                  entry.service = newInstance;
                }
              }
            } else {
              log.warn("Instance data has been deleted for: " + instance);
            }
          }
        };
    nodeCache.getListenable().addListener(listener);
    return nodeCache;
  }
 @Override
 public void updateService(final ServiceInstance<T> service) throws Exception {
   Entry<T> entry = services.get(service.getId());
   if (entry == null) {
     throw new Exception("Service not registered: " + service);
   }
   synchronized (entry) {
     entry.service = service;
     byte[] bytes = serializer.serialize(service);
     String path = pathForInstance(service.getName(), service.getId());
     client.setData().forPath(path, bytes);
   }
 }
  @VisibleForTesting
  protected void internalRegisterService(ServiceInstance<T> service) throws Exception {
    byte[] bytes = serializer.serialize(service);
    String path = pathForInstance(service.getName(), service.getId());

    final int MAX_TRIES = 2;
    boolean isDone = false;
    for (int i = 0; !isDone && (i < MAX_TRIES); ++i) {
      try {
        CreateMode mode =
            (service.getServiceType() == ServiceType.DYNAMIC)
                ? CreateMode.EPHEMERAL
                : CreateMode.PERSISTENT;
        client.create().creatingParentsIfNeeded().withMode(mode).forPath(path, bytes);
        isDone = true;
      } catch (KeeperException.NodeExistsException e) {
        client.delete().forPath(path); // must delete then re-create so that watchers fire
      }
    }
  }