protected <T> ICompletableFuture<T> replaceInternal(
      K key,
      V oldValue,
      V newValue,
      ExpiryPolicy expiryPolicy,
      boolean hasOldValue,
      boolean withCompletionEvent,
      boolean async) {
    final long start = System.nanoTime();
    ensureOpen();
    if (hasOldValue) {
      validateNotNull(key, oldValue, newValue);
      CacheProxyUtil.validateConfiguredTypes(cacheConfig, key, oldValue, newValue);
    } else {
      validateNotNull(key, newValue);
      CacheProxyUtil.validateConfiguredTypes(cacheConfig, key, newValue);
    }

    final Data keyData = toData(key);
    final Data oldValueData = toData(oldValue);
    final Data newValueData = toData(newValue);
    final Data expiryPolicyData = toData(expiryPolicy);
    final int completionId = withCompletionEvent ? nextCompletionId() : -1;
    ClientMessage request =
        CacheReplaceCodec.encodeRequest(
            nameWithPrefix, keyData, oldValueData, newValueData, expiryPolicyData, completionId);
    ClientInvocationFuture future;
    try {
      future = invoke(request, keyData, completionId);
      invalidateNearCache(keyData);
    } catch (Exception e) {
      throw ExceptionUtil.rethrow(e);
    }

    ClientDelegatingFuture delegatingFuture =
        new ClientDelegatingFuture<T>(
            future, clientContext.getSerializationService(), replaceResponseDecoder);
    if (async && statisticsEnabled) {
      delegatingFuture.andThen(
          new ExecutionCallback<Object>() {
            public void onResponse(Object responseData) {
              Object response = clientContext.getSerializationService().toObject(responseData);
              handleStatisticsOnReplace(false, start, response);
            }

            public void onFailure(Throwable t) {}
          });
    }
    return delegatingFuture;
  }
 @Override
 public void loadAll(
     Set<? extends K> keys, boolean replaceExistingValues, CompletionListener completionListener) {
   ensureOpen();
   validateNotNull(keys);
   for (K key : keys) {
     CacheProxyUtil.validateConfiguredTypes(cacheConfig, key);
   }
   validateCacheLoader(completionListener);
   HashSet<Data> keysData = new HashSet<Data>();
   for (K key : keys) {
     keysData.add(toData(key));
   }
   ClientMessage request =
       CacheLoadAllCodec.encodeRequest(nameWithPrefix, keysData, replaceExistingValues);
   try {
     submitLoadAllTask(request, completionListener);
   } catch (Exception e) {
     if (completionListener != null) {
       completionListener.onException(e);
     }
     throw new CacheException(e);
   }
 }
 protected void validateConfiguredTypes(Set<? extends K> keys) throws ClassCastException {
   for (K key : keys) {
     CacheProxyUtil.validateConfiguredTypes(cacheConfig, false, key);
   }
 }
 protected void validateConfiguredTypes(boolean validateValues, K key, V... values)
     throws ClassCastException {
   CacheProxyUtil.validateConfiguredTypes(cacheConfig, validateValues, key, values);
 }
  protected Object putIfAbsentInternal(
      final K key,
      final V value,
      final ExpiryPolicy expiryPolicy,
      final boolean withCompletionEvent,
      final boolean async) {
    final long start = System.nanoTime();
    ensureOpen();
    validateNotNull(key, value);
    CacheProxyUtil.validateConfiguredTypes(cacheConfig, key, value);
    final Data keyData = toData(key);
    final Data valueData = toData(value);
    final Data expiryPolicyData = toData(expiryPolicy);
    final int completionId = withCompletionEvent ? nextCompletionId() : -1;
    ClientMessage request =
        CachePutIfAbsentCodec.encodeRequest(
            nameWithPrefix, keyData, valueData, expiryPolicyData, completionId);
    ClientInvocationFuture future;
    try {
      future = invoke(request, keyData, completionId);
    } catch (Exception e) {
      throw ExceptionUtil.rethrow(e);
    }
    ClientDelegatingFuture delegatingFuture =
        new ClientDelegatingFuture<Boolean>(
            future, clientContext.getSerializationService(), putIfAbsentResponseDecoder);
    if (!async) {
      try {
        Object response = delegatingFuture.get();
        if (nearCache != null) {
          if (cacheOnUpdate) {
            storeInNearCache(keyData, valueData, value);
          } else {
            invalidateNearCache(keyData);
          }
        }
        if (statisticsEnabled) {
          handleStatisticsOnPutIfAbsent(start, (Boolean) response);
        }
        return response;
      } catch (Throwable e) {
        throw ExceptionUtil.rethrowAllowedTypeFirst(e, CacheException.class);
      }
    } else {
      if (nearCache != null || statisticsEnabled) {
        delegatingFuture.andThen(
            new ExecutionCallback<Object>() {
              @Override
              public void onResponse(Object responseData) {
                if (nearCache != null) {
                  if (cacheOnUpdate) {
                    storeInNearCache(keyData, valueData, value);
                  } else {
                    invalidateNearCache(keyData);
                  }
                }
                if (statisticsEnabled) {
                  Object response = clientContext.getSerializationService().toObject(responseData);
                  handleStatisticsOnPutIfAbsent(start, (Boolean) response);
                }
              }

              @Override
              public void onFailure(Throwable t) {}
            });
      }
      return delegatingFuture;
    }
  }