private List<Integer> findBucketOwners(final Set<Integer> bucketIdsToConsider,
      HashMap<InternalDistributedMember, List<Integer>> nodeToBucketMap) {
    final List<Integer> bucketIds = new ArrayList<>();
    // Get all local buckets
    PartitionedRegionDataStore dataStore = pr.getDataStore();
    if (dataStore != null) {
      for (Integer bid : bucketIdsToConsider) {
        if (dataStore.isManagingBucket(bid)) {
          bucketIds.add(bid);
        }
      }
      if (bucketIds.size() > 0) {
        List<Integer> localBucketIds = new ArrayList<>(bucketIds);
        nodeToBucketMap.put(pr.getMyId(), localBucketIds);
        // All the buckets are hosted locally.
        if (localBucketIds.size() == bucketIdsToConsider.size()) {
          return bucketIds;
        }
      }
    }
    final List<InternalDistributedMember> allNodes = getAllNodes(pr.getRegionAdvisor());
    // Put the failed members on the end of the list.
    if (failedMembers != null && !failedMembers.isEmpty()) {
      allNodes.removeAll(failedMembers);
      allNodes.addAll(failedMembers);
    }
    int totalBucketsToQuery = bucketIdsToConsider.size();
    for (Iterator<InternalDistributedMember> dsItr = allNodes.iterator(); dsItr.hasNext()
        && (bucketIds.size() < totalBucketsToQuery);) {
      InternalDistributedMember nd = dsItr.next();
      final List<Integer> buckets = new ArrayList<>();
      for (Integer bid : bucketIdsToConsider) {
        if (!bucketIds.contains(bid)) {
          final Set owners = getBucketOwners(bid);
          if (owners.contains(nd)) {
            buckets.add(bid);
            bucketIds.add(bid);
          }
        }
      }
      if (!buckets.isEmpty()) {
        nodeToBucketMap.put(nd, buckets);
      }
    }
    return bucketIds;
  }
@return Map of {@link InternalDistributedMember} to {@link ArrayList} of Integers
geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionQueryEvaluator.java