code: @Override
    public <T> OperationFuture<CASResponse>
    asyncCAS(String key, long casId, int exp, T value, Transcoder<T> tc) {
      CachedData co = tc.encode(value);
      final CountDownLatch latch = new CountDownLatch(1);
      final OperationFuture<CASResponse> rv =
        new OperationFuture<CASResponse>(key, latch, operationTimeout,
        executorService);
      Operation op = opFact.cas(StoreType.set, key, casId, co.getFlags(), exp,
          co.getData(), new StoreOperation.Callback() {
              @Override
              public void receivedStatus(OperationStatus val) {
                if (val instanceof CASOperationStatus) {
                  rv.set(((CASOperationStatus) val).getCASResponse(), val);
                } else if (val instanceof CancelledOperationStatus) {
                  getLogger().debug("CAS operation cancelled");
                } else if (val instanceof TimedOutOperationStatus) {
                  getLogger().debug("CAS operation timed out");
                } else {
                  throw new RuntimeException("Unhandled state: " + val);
                }
              }
              @Override
              public void gotData(String key, long cas) {
                rv.setCas(cas);
              }
              @Override
              public void complete() {
                latch.countDown();
                rv.signalComplete();
              }
            });
      rv.setOperation(op);
      mconn.enqueueOperation(key, op);
      return rv;
    }
docs: Asynchronous CAS operation.
  
  @param <T>
  @param key the key
  @param casId the CAS identifier (from a gets operation)
  @param exp the expiration of this object
  @param value the new value
  @param tc the transcoder to serialize and unserialize the value
  @return a future that will indicate the status of the CAS
  @throws IllegalStateException in the rare circumstance where queue is too
  full to accept any more requests