public HashMap<Integer, Integer> queryOutNeighborsAndCombine(final Collection<Integer> queryVertices) {
        HashMap<Integer, Integer> results;
        List<Future<HashMap<Integer, Integer>>> queryFutures = new ArrayList<Future<HashMap<Integer, Integer>>>();

        /* Check which ones are in cache */
        long st = System.currentTimeMillis();
        HashMap<Integer, Integer> fromCache = new HashMap<Integer, Integer>(1000000);

        logger.info("Cached queries took: " + (System.currentTimeMillis() - st));

        /* Execute queries in parallel */
        for(Shard shard : shards) {
            final Shard _shard = shard;
            queryFutures.add(executor.submit(new Callable<HashMap<Integer, Integer>>() {
                @Override
                public HashMap<Integer, Integer> call() throws Exception {
                    HashMap<Integer, Integer> edges = _shard.queryAndCombine(queryVertices);
                    return edges;
                }
            }));
        }

        /* Combine
        */
        try {
            results = fromCache;

            for(int i=0; i < queryFutures.size(); i++) {
                HashMap<Integer, Integer> shardResults = queryFutures.get(i).get();

                for(Map.Entry<Integer, Integer> e : shardResults.entrySet()) {
                    if (results.containsKey(e.getKey())) {
                        results.put(e.getKey(), e.getValue() + results.get(e.getKey()));
                    } else {
                        results.put(e.getKey(), e.getValue());
                    }
                }
            }

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }


        return  results;
    }