private Future<Iterable<Object>> invokeCohorts(Object message) {
    List<Future<Object>> futureList = Lists.newArrayListWithCapacity(cohorts.size());
    for (ActorSelection cohort : cohorts) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Tx {}: Sending {} to cohort {}", transactionId, message, cohort);
      }
      futureList.add(
          actorContext.executeOperationAsync(
              cohort, message, actorContext.getTransactionCommitOperationTimeout()));
    }

    return Futures.sequence(futureList, actorContext.getClientDispatcher());
  }
  private void finishCanCommit(final SettableFuture<Boolean> returnFuture) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Tx {} finishCanCommit", transactionId);
    }

    // For empty transactions return immediately
    if (cohorts.size() == 0) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Tx {}: canCommit returning result: {}", transactionId, true);
      }
      returnFuture.set(Boolean.TRUE);
      return;
    }

    final Object message = new CanCommitTransaction(transactionId).toSerializable();

    final Iterator<ActorSelection> iterator = cohorts.iterator();

    final OnComplete<Object> onComplete =
        new OnComplete<Object>() {
          @Override
          public void onComplete(Throwable failure, Object response) throws Throwable {
            if (failure != null) {
              if (LOG.isDebugEnabled()) {
                LOG.debug("Tx {}: a canCommit cohort Future failed: {}", transactionId, failure);
              }
              returnFuture.setException(failure);
              return;
            }

            boolean result = true;
            if (response.getClass().equals(CanCommitTransactionReply.SERIALIZABLE_CLASS)) {
              CanCommitTransactionReply reply =
                  CanCommitTransactionReply.fromSerializable(response);
              if (!reply.getCanCommit()) {
                result = false;
              }
            } else {
              LOG.error("Unexpected response type {}", response.getClass());
              returnFuture.setException(
                  new IllegalArgumentException(
                      String.format("Unexpected response type %s", response.getClass())));
              return;
            }

            if (iterator.hasNext() && result) {
              Future<Object> future =
                  actorContext.executeOperationAsync(
                      iterator.next(),
                      message,
                      actorContext.getTransactionCommitOperationTimeout());
              future.onComplete(this, actorContext.getClientDispatcher());
            } else {
              if (LOG.isDebugEnabled()) {
                LOG.debug("Tx {}: canCommit returning result: {}", transactionId, result);
              }
              returnFuture.set(Boolean.valueOf(result));
            }
          }
        };

    Future<Object> future =
        actorContext.executeOperationAsync(
            iterator.next(), message, actorContext.getTransactionCommitOperationTimeout());
    future.onComplete(onComplete, actorContext.getClientDispatcher());
  }