@Override
 public CompletableFuture<Versioned<V>> putAndGet(K key, V value) {
   checkNotNull(key, ERROR_NULL_KEY);
   checkNotNull(value, ERROR_NULL_VALUE);
   checkIfUnmodifiable();
   return database
       .putAndGet(name, keyCache.getUnchecked(key), serializer.encode(value))
       .thenApply(this::unwrapResult)
       .thenApply(
           v -> {
             Versioned<byte[]> rawNewValue = v.newValue();
             return new Versioned<>(
                 serializer.decode(rawNewValue.value()),
                 rawNewValue.version(),
                 rawNewValue.creationTime());
           });
 }
 @Override
 public CompletableFuture<Optional<Versioned<V>>> replaceAndGet(
     K key, long oldVersion, V newValue) {
   checkNotNull(key, ERROR_NULL_KEY);
   checkNotNull(newValue, ERROR_NULL_VALUE);
   checkIfUnmodifiable();
   return database
       .replaceAndGet(name, keyCache.getUnchecked(key), oldVersion, serializer.encode(newValue))
       .thenApply(this::unwrapResult)
       .thenApply(
           v -> {
             if (v.updated()) {
               Versioned<byte[]> rawNewValue = v.newValue();
               return Optional.of(
                   new Versioned<>(
                       serializer.decode(rawNewValue.value()),
                       rawNewValue.version(),
                       rawNewValue.creationTime()));
             } else {
               return Optional.empty();
             }
           });
 }