@Override
 public CompletableFuture<Void> set(V value) {
   final MeteringAgent.Context newTimer = monitor.startTimer(SET);
   if (value == null) {
     return backingMap.remove(name).whenComplete((r, e) -> newTimer.stop(e)).thenApply(v -> null);
   }
   return backingMap
       .put(name, serializer.encode(value))
       .whenComplete((r, e) -> newTimer.stop(e))
       .thenApply(v -> null);
 }
 @Override
 public CompletableFuture<V> getAndSet(V value) {
   final MeteringAgent.Context newTimer = monitor.startTimer(GET_AND_SET);
   if (value == null) {
     return backingMap
         .remove(name)
         .thenApply(Versioned::valueOrNull)
         .thenApply(v -> v == null ? null : serializer.<V>decode(v))
         .whenComplete((r, e) -> newTimer.stop(e));
   }
   return backingMap
       .put(name, serializer.encode(value))
       .thenApply(Versioned::valueOrNull)
       .thenApply(v -> v == null ? null : serializer.<V>decode(v))
       .whenComplete((r, e) -> newTimer.stop(e));
 }
 @Override
 public CompletableFuture<Boolean> compareAndSet(V expect, V update) {
   final MeteringAgent.Context newTimer = monitor.startTimer(COMPARE_AND_SET);
   return backingMap
       .replace(name, serializer.encode(expect), serializer.encode(update))
       .whenComplete((r, e) -> newTimer.stop(e));
 }
 @Override
 public CompletableFuture<Void> addListener(AtomicValueEventListener<V> listener) {
   checkNotNull(listener, "listener must not be null");
   final MeteringAgent.Context newTimer = monitor.startTimer(ADD_LISTENER);
   MapEventListener<String, byte[]> mapListener =
       listeners.computeIfAbsent(listener, key -> new InternalMapValueEventListener(listener));
   return backingMap.addListener(mapListener).whenComplete((r, e) -> newTimer.stop(e));
 }
 @Override
 public CompletableFuture<V> get() {
   final MeteringAgent.Context newTimer = monitor.startTimer(GET);
   return backingMap
       .get(name)
       .thenApply(Versioned::valueOrNull)
       .thenApply(v -> v == null ? null : serializer.<V>decode(v))
       .whenComplete((r, e) -> newTimer.stop(e));
 }
 @Override
 public CompletableFuture<Void> removeListener(AtomicValueEventListener<V> listener) {
   checkNotNull(listener, "listener must not be null");
   final MeteringAgent.Context newTimer = monitor.startTimer(REMOVE_LISTENER);
   MapEventListener<String, byte[]> mapListener = listeners.remove(listener);
   if (mapListener != null) {
     return backingMap.removeListener(mapListener).whenComplete((r, e) -> newTimer.stop(e));
   } else {
     newTimer.stop(null);
     return CompletableFuture.completedFuture(null);
   }
 }