@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;
  }
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
src/main/java/net/spy/memcached/MemcachedClient.java