private boolean waitForTasksToFinish() throws Exception {
        
        Boolean succeeded = true;
        
        // Tracking state for multiple exceptions, if any
        List<StackTraceElement> stackTraces = new ArrayList<StackTraceElement>();
        StringBuilder sb = new StringBuilder();
        int exCount = 0;
        
        for (Future<Boolean> future : futures) {
            try {
                if (!future.get()) {
                    cancel();
                    succeeded = false;
                }
            }
            catch (Exception e) {
                error.compareAndSet(null, e);
                cancel();
                succeeded = false;
                
                exCount++;
                sb.append("ex" + exCount + ": ").append(e.getMessage()).append("\n");
                StackTraceElement[] stackTrace = e.getStackTrace();
                if (stackTrace != null && stackTrace.length > 0) {
                    StackTraceElement delimiterSE = new StackTraceElement("StackTrace: ex" + exCount, "", "", 0);
                    stackTraces.add(delimiterSE);
                    for (StackTraceElement se : stackTrace) {
                        stackTraces.add(se);
                    }
                }
            }
        }
        
        if (this.rowFunction instanceof Flushable) {
            ((Flushable)rowFunction).flush();
        }
        
        if (exCount > 0) {
            String exMessage = sb.toString();
            StackTraceElement[] seArray = stackTraces.toArray(new StackTraceElement[stackTraces.size()]);
            Exception ex = new Exception(exMessage);
            ex.setStackTrace(seArray);
            throw ex;
        }
        return succeeded;
    }
private boolean waitForTasksToFinish ( ) throws Exception { Boolean succeeded = true ; List < StackTraceElement > stackTraces = new ArrayList < StackTraceElement > ( ) ; StringBuilder sb = new StringBuilder ( ) ; int exCount = 0 ; for ( Future < Boolean > future : futures ) { try { if ( ! future . get ( ) ) { cancel ( ) ; succeeded = false ; } } catch ( Exception e ) { error . compareAndSet ( null , e ) ; cancel ( ) ; succeeded = false ; exCount ++ ; sb . append ( "ex" + exCount + ": " ) . append ( e . getMessage ( ) ) . append ( "\n" ) ; StackTraceElement [ ] stackTrace = e . getStackTrace ( ) ; if ( stackTrace != null && stackTrace . length > 0 ) { StackTraceElement delimiterSE = new StackTraceElement ( "StackTrace: ex" + exCount , "" , "" , 0 ) ; stackTraces . add ( delimiterSE ) ; for ( StackTraceElement se : stackTrace ) { stackTraces . add ( se ) ; } } } } if ( this . rowFunction instanceof Flushable ) { ( ( Flushable ) rowFunction ) . flush ( ) ; } if ( exCount > 0 ) { String exMessage = sb . toString ( ) ; StackTraceElement [ ] seArray = stackTraces . toArray ( new StackTraceElement [ stackTraces . size ( ) ] ) ; Exception ex = new Exception ( exMessage ) ; ex . setStackTrace ( seArray ) ; throw ex ; } return succeeded ; }
Wait for all tasks to finish.

@param futures
@return true if all tasks returned true or false otherwise.