Program: 50017
Project: 50017
Buggy source:
private Object txnalRemove(ClusterOperation operation,String name,Object key,Object value,long timeout){
  ThreadContext threadContext=ThreadContext.get();
  TransactionImpl txn=threadContext.getCallContext().getTransaction();
  if (txn != null && txn.getStatus() == Transaction.TXN_STATUS_ACTIVE) {
    if (!txn.has(name,key)) {
      MLock mlock=new MLock();
      boolean locked=mlock.lockAndGetValue(name,key,timeout);
      if (!locked) {
        throwCME(key);
      }
      Object oldObject=null;
      Data oldValue=mlock.oldValue;
      if (oldValue != null) {
        oldObject=threadContext.toObject(oldValue);
      }
      int removedValueCount=0;
      if (oldObject != null) {
        if (oldObject instanceof DistributedTimeoutException) {
          return oldObject;
        }
        if (oldObject instanceof CMap.Values) {
          CMap.Values values=(CMap.Values)oldObject;
          removedValueCount=values.size();
        }
 else {
          removedValueCount=1;
        }
      }
      txn.attachRemoveOp(name,key,value,(oldObject == null),removedValueCount);
      return oldObject;
    }
 else {
      return txn.attachRemoveOp(name,key,value,false);
    }
  }
 else {
    Object oldValue=objectCall(operation,name,key,value,timeout,-1);
    if (oldValue != null) {
      if (oldValue instanceof AddressAwareException) {
        rethrowException(operation,(AddressAwareException)oldValue);
      }
      if (!(oldValue instanceof DistributedTimeoutException)) {
        backup(CONCURRENT_MAP_BACKUP_REMOVE);
      }
    }
    return oldValue;
  }
}

Fixed version (ground truth):
private Object txnalRemove(ClusterOperation operation,String name,Object key,Object value,long timeout){
  ThreadContext threadContext=ThreadContext.get();
  TransactionImpl txn=threadContext.getCallContext().getTransaction();
  if (txn != null && txn.getStatus() == Transaction.TXN_STATUS_ACTIVE) {
    if (!txn.has(name,key)) {
      MLock mlock=new MLock();
      boolean locked=mlock.lockAndGetValue(name,key,timeout);
      if (!locked) {
        throwCME(key);
      }
      Object oldObject=null;
      Data oldValue=mlock.oldValue;
      if (oldValue != null) {
        oldObject=threadContext.isClient() ? oldValue : threadContext.toObject(oldValue);
      }
      int removedValueCount=0;
      if (oldObject != null) {
        if (oldObject instanceof DistributedTimeoutException) {
          return oldObject;
        }
        if (oldObject instanceof CMap.Values) {
          CMap.Values values=(CMap.Values)oldObject;
          removedValueCount=values.size();
        }
 else {
          removedValueCount=1;
        }
      }
      txn.attachRemoveOp(name,key,value,(oldObject == null),removedValueCount);
      return oldObject;
    }
 else {
      return txn.attachRemoveOp(name,key,value,false);
    }
  }
 else {
    Object oldValue=objectCall(operation,name,key,value,timeout,-1);
    if (oldValue != null) {
      if (oldValue instanceof AddressAwareException) {
        rethrowException(operation,(AddressAwareException)oldValue);
      }
      if (!(oldValue instanceof DistributedTimeoutException)) {
        backup(CONCURRENT_MAP_BACKUP_REMOVE);
      }
    }
    return oldValue;
  }
}