protected Object getInternal(K key, ExpiryPolicy expiryPolicy, boolean async) {
    ensureOpen();
    validateNotNull(key);
    final Data keyData = toData(key);
    Object cached = getFromNearCache(keyData, async);
    if (cached != null) {
      return cached;
    }
    final Data expiryPolicyData = toData(expiryPolicy);
    ClientMessage request = CacheGetCodec.encodeRequest(nameWithPrefix, keyData, expiryPolicyData);
    ClientInvocationFuture future;
    try {
      final int partitionId = clientContext.getPartitionService().getPartitionId(key);
      final HazelcastClientInstanceImpl client =
          (HazelcastClientInstanceImpl) clientContext.getHazelcastInstance();
      final ClientInvocation clientInvocation = new ClientInvocation(client, request, partitionId);
      future = clientInvocation.invoke();
    } catch (Exception e) {
      throw ExceptionUtil.rethrow(e);
    }
    SerializationService serializationService = clientContext.getSerializationService();
    ClientDelegatingFuture<V> delegatingFuture =
        new ClientDelegatingFuture<V>(future, serializationService, cacheGetResponseDecoder);
    if (async) {
      if (nearCache != null) {
        delegatingFuture.andThenInternal(
            new ExecutionCallback<Data>() {
              public void onResponse(Data valueData) {
                storeInNearCache(keyData, valueData, null);
              }

              public void onFailure(Throwable t) {}
            });
      }
      return delegatingFuture;
    } else {
      try {
        Object value = delegatingFuture.get();
        if (nearCache != null) {
          storeInNearCache(keyData, (Data) delegatingFuture.getResponse(), null);
        }
        if (!(value instanceof Data)) {
          return value;
        } else {
          return serializationService.toObject(value);
        }
      } catch (Throwable e) {
        throw ExceptionUtil.rethrowAllowedTypeFirst(e, CacheException.class);
      }
    }
  }
 @Override
 public <T> T decodeClientMessage(ClientMessage clientMessage) {
   return (T) CacheGetCodec.decodeResponse(clientMessage).response;
 }