private void sumAccounts(String transactionId, double expected) throws Throwable {
   Query.Builder queryBuilder =
       Query.Builder.create()
           .addKindFieldClause(BankAccountServiceState.class)
           .addFieldClause(
               ServiceDocument.FIELD_NAME_SELF_LINK,
               BankAccountFactoryService.SELF_LINK
                   + UriUtils.URI_PATH_CHAR
                   + this.baseAccountId
                   + UriUtils.URI_WILDCARD_CHAR,
               MatchType.WILDCARD);
   // we need to sum up the account balances in a logical 'snapshot'. rigt now the only way to do
   // it
   // is using a transaction, so if transactionId is null we're creating a new transaction
   boolean createNewTransaction = transactionId == null;
   if (createNewTransaction) {
     transactionId = newTransaction();
     this.host.log("Created new transaction %s for snapshot read", transactionId);
   } else {
     queryBuilder.addFieldClause(ServiceDocument.FIELD_NAME_TRANSACTION_ID, transactionId);
   }
   QueryTask task = QueryTask.Builder.createDirectTask().setQuery(queryBuilder.build()).build();
   this.host.createQueryTaskService(task, false, true, task, null);
   double sum = 0;
   for (String serviceSelfLink : task.results.documentLinks) {
     String accountId = serviceSelfLink.substring(serviceSelfLink.lastIndexOf('/') + 1);
     for (int i = 0; i < RETRIES_IN_CASE_OF_CONFLICTS; i++) {
       try {
         this.host.log("Trying to read account %s", accountId);
         BankAccountServiceState account = getAccount(transactionId, accountId);
         sum += account.balance;
         this.host.log("Successfully read account %s, runnin sum=%f", accountId, sum);
         break;
       } catch (IllegalStateException ex) {
         this.host.log(
             "Could not read account %s probably due to a transactional conflict", accountId);
         Thread.sleep(new Random().nextInt(SLEEP_BETWEEN_RETRIES_MILLIS));
         if (i == RETRIES_IN_CASE_OF_CONFLICTS - 1) {
           this.host.log("Giving up reading account %s", accountId);
         } else {
           this.host.log("Retrying reading account %s", accountId);
         }
       }
     }
   }
   if (createNewTransaction) {
     commit(transactionId);
   }
   assertEquals(expected, sum, 0);
 }
 private void countAccounts(String transactionId, long expected) throws Throwable {
   Query.Builder queryBuilder =
       Query.Builder.create()
           .addKindFieldClause(BankAccountServiceState.class)
           .addFieldClause(
               ServiceDocument.FIELD_NAME_SELF_LINK,
               BankAccountFactoryService.SELF_LINK
                   + UriUtils.URI_PATH_CHAR
                   + this.baseAccountId
                   + UriUtils.URI_WILDCARD_CHAR,
               MatchType.WILDCARD);
   if (transactionId != null) {
     queryBuilder.addFieldClause(ServiceDocument.FIELD_NAME_TRANSACTION_ID, transactionId);
   }
   QueryTask task = QueryTask.Builder.createDirectTask().setQuery(queryBuilder.build()).build();
   this.host.createQueryTaskService(task, false, true, task, null);
   assertEquals(expected, task.results.documentCount.longValue());
 }