public void waitForAllJobsToComplete() {
        ArrayList<Exception> errors = new ArrayList<>();
        synchronized (jobs) {
            while (jobs.size() > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ignore) {
                }
                ArrayList<Future<Long>> done = new ArrayList<>();
                ArrayList<Future<Long>> erroneous = new ArrayList<>();
                errors.clear();
                for (Future<Long> f : jobs) {
                    if (f.isDone() || f.isCancelled()) {
                        try {
                            f.get();
                            done.add(f);
                        } catch (Exception e) {
                            erroneous.add(f);
                            errors.add(e);
                        }
                    }
                }
                for (Future<Long> f : done) {
                    jobs.remove(f);
                }
                for (Future<Long> f : erroneous) {
                    jobs.remove(f);
                }
            }
        }
        //
        for (Exception e: errors) {
            System.out.println("Error: " + e);
        }
    }