protected ShardFetchSearchRequest createFetchRequest(
     QuerySearchResult queryResult,
     AtomicArray.Entry<IntArrayList> entry,
     ScoreDoc[] lastEmittedDocPerShard) {
   final ScoreDoc lastEmittedDoc =
       (lastEmittedDocPerShard != null) ? lastEmittedDocPerShard[entry.index] : null;
   return new ShardFetchSearchRequest(request, queryResult.id(), entry.value, lastEmittedDoc);
 }
    private void executeFetchPhase() {
      sortedShardList = searchPhaseController.sortDocs(queryResults);
      AtomicArray<ExtTIntArrayList> docIdsToLoad =
          new AtomicArray<ExtTIntArrayList>(queryResults.length());
      searchPhaseController.fillDocIdsToLoad(docIdsToLoad, sortedShardList);

      if (docIdsToLoad.asList().isEmpty()) {
        finishHim();
      }

      final AtomicInteger counter = new AtomicInteger(docIdsToLoad.asList().size());

      for (final AtomicArray.Entry<ExtTIntArrayList> entry : docIdsToLoad.asList()) {
        ExtTIntArrayList docIds = entry.value;
        final QuerySearchResult querySearchResult = queryResults.get(entry.index);
        FetchSearchRequest fetchSearchRequest =
            new FetchSearchRequest(request, querySearchResult.id(), docIds);
        DiscoveryNode node = nodes.get(querySearchResult.shardTarget().nodeId());
        searchService.sendExecuteFetch(
            node,
            fetchSearchRequest,
            new SearchServiceListener<FetchSearchResult>() {
              @Override
              public void onResult(FetchSearchResult result) {
                result.shardTarget(querySearchResult.shardTarget());
                fetchResults.set(entry.index, result);
                if (counter.decrementAndGet() == 0) {
                  finishHim();
                }
              }

              @Override
              public void onFailure(Throwable t) {
                if (logger.isDebugEnabled()) {
                  logger.debug("Failed to execute fetch phase", t);
                }
                successfulOps.decrementAndGet();
                if (counter.decrementAndGet() == 0) {
                  finishHim();
                }
              }
            });
      }
    }