public void start() {
   if (shardsIts.size() == 0) {
     // no shards
     try {
       listener.onResponse(newResponse(request, new AtomicReferenceArray(0), clusterState));
     } catch (Throwable e) {
       listener.onFailure(e);
     }
     return;
   }
   request.beforeStart();
   // count the local operations, and perform the non local ones
   int shardIndex = -1;
   for (final ShardIterator shardIt : shardsIts) {
     shardIndex++;
     final ShardRouting shard = shardIt.nextOrNull();
     if (shard != null) {
       performOperation(shardIt, shard, shardIndex);
     } else {
       // really, no shards active in this group
       onOperation(
           null, shardIt, shardIndex, new NoShardAvailableActionException(shardIt.shardId()));
     }
   }
 }
 public void start() {
   if (shardsIts.size() == 0) {
     // no shards
     try {
       listener.onResponse(newResponse(request, new AtomicReferenceArray(0), clusterState));
     } catch (Throwable e) {
       listener.onFailure(e);
     }
   }
   request.beforeStart();
   // count the local operations, and perform the non local ones
   int localOperations = 0;
   int shardIndex = -1;
   for (final ShardIterator shardIt : shardsIts) {
     shardIndex++;
     final ShardRouting shard = shardIt.firstOrNull();
     if (shard != null) {
       if (shard.currentNodeId().equals(nodes.localNodeId())) {
         localOperations++;
       } else {
         // do the remote operation here, the localAsync flag is not relevant
         performOperation(shardIt, shardIndex, true);
       }
     } else {
       // really, no shards active in this group
       onOperation(
           null, shardIt, shardIndex, new NoShardAvailableActionException(shardIt.shardId()));
     }
   }
   // we have local operations, perform them now
   if (localOperations > 0) {
     if (request.operationThreading() == BroadcastOperationThreading.SINGLE_THREAD) {
       request.beforeLocalFork();
       threadPool
           .executor(executor)
           .execute(
               new Runnable() {
                 @Override
                 public void run() {
                   int shardIndex = -1;
                   for (final ShardIterator shardIt : shardsIts) {
                     shardIndex++;
                     final ShardRouting shard = shardIt.firstOrNull();
                     if (shard != null) {
                       if (shard.currentNodeId().equals(nodes.localNodeId())) {
                         performOperation(shardIt, shardIndex, false);
                       }
                     }
                   }
                 }
               });
     } else {
       boolean localAsync =
           request.operationThreading() == BroadcastOperationThreading.THREAD_PER_SHARD;
       if (localAsync) {
         request.beforeLocalFork();
       }
       shardIndex = -1;
       for (final ShardIterator shardIt : shardsIts) {
         shardIndex++;
         final ShardRouting shard = shardIt.firstOrNull();
         if (shard != null) {
           if (shard.currentNodeId().equals(nodes.localNodeId())) {
             performOperation(shardIt, shardIndex, localAsync);
           }
         }
       }
     }
   }
 }