// Path: src/main/java/org/junit/runners/model/MultipleFailureException.java
// public class MultipleFailureException extends Exception {
//     private static final long serialVersionUID = 1L;
// 
//     /*
//      * We have to use the f prefix until the next major release to ensure
//      * serialization compatibility. 
//      * See https://github.com/junit-team/junit4/issues/976
//      */
//     private final List<Throwable> fErrors;
// 
//     public MultipleFailureException(List<Throwable> errors) {
//         if (errors.isEmpty()) {
//             throw new IllegalArgumentException(
//                     "List of Throwables must not be empty");
//         }
//         this.fErrors = new ArrayList<Throwable>(errors.size());
//         for (Throwable error : errors) {
//             if (error instanceof AssumptionViolatedException) {
//                 error = new TestCouldNotBeSkippedException((AssumptionViolatedException) error);
//             }
//             fErrors.add(error);
//         }
//     }
// 
//     public List<Throwable> getFailures() {
//         return Collections.unmodifiableList(fErrors);
//     }
// 
//     @Override
//     public String getMessage() {
//         StringBuilder sb = new StringBuilder(
//                 String.format("There were %d errors:", fErrors.size()));
//         for (Throwable e : fErrors) {
//             sb.append(String.format("%n  %s(%s)", e.getClass().getName(), e.getMessage()));
//         }
//         return sb.toString();
//     }
// 
//     @Override
//     public void printStackTrace() {
//         for (Throwable e: fErrors) {
//             e.printStackTrace();
//         }
//     }
//     
//     @Override
//     public void printStackTrace(PrintStream s) {
//         for (Throwable e: fErrors) {
//             e.printStackTrace(s);
//         }
//     }
//     
//     @Override
//     public void printStackTrace(PrintWriter s) {
//         for (Throwable e: fErrors) {
//             e.printStackTrace(s);
//         }
//     }
//     
//     /**
//      * Asserts that a list of throwables is empty. If it isn't empty,
//      * will throw {@link MultipleFailureException} (if there are
//      * multiple throwables in the list) or the first element in the list
//      * (if there is only one element).
//      *
//      * @param errors list to check
//      * @throws Exception or Error if the list is not empty
//      */
//     @SuppressWarnings("deprecation")
//     public static void assertEmpty(List<Throwable> errors) throws Exception {
//         if (errors.isEmpty()) {
//             return;
//         }
//         if (errors.size() == 1) {
//             throw Throwables.rethrowAsException(errors.get(0));
//         }
// 
//         /*
//            * Many places in the code are documented to throw
//            * org.junit.internal.runners.model.MultipleFailureException.
//            * That class now extends this one, so we throw the internal
//            * exception in case developers have tests that catch
//            * MultipleFailureException.
//            */
//         throw new org.junit.internal.runners.model.MultipleFailureException(errors);
//     }
// }


import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.internal.management.ManagementFactory;
import org.junit.internal.management.ThreadMXBean;
import org.junit.runners.model.MultipleFailureException;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestTimedOutException;
    private Throwable getResult(FutureTask<Throwable> task, Thread thread) {
        try {
            if (timeout > 0) {
                return task.get(timeout, timeUnit);
            } else {
                return task.get();
            }
        } catch (InterruptedException e) {
            return e; // caller will re-throw; no need to call Thread.interrupt()
        } catch (ExecutionException e) {
            // test failed; have caller re-throw the exception thrown by the test
            return e.getCause();
        } catch (TimeoutException e) {
            return createTimeoutException(thread);
        }
    }

    private Exception createTimeoutException(Thread thread) {
        StackTraceElement[] stackTrace = thread.getStackTrace();
        final Thread stuckThread = lookForStuckThread ? getStuckThread(thread) : null;
        Exception currThreadException = new TestTimedOutException(timeout, timeUnit);
        if (stackTrace != null) {
            currThreadException.setStackTrace(stackTrace);
            thread.interrupt();
        }
        if (stuckThread != null) {
            Exception stuckThreadException = 
                new Exception("Appears to be stuck in thread " +
                               stuckThread.getName());
            stuckThreadException.setStackTrace(getStackTrace(stuckThread));
// Path: src/main/java/org/junit/runners/model/MultipleFailureException.java
// public class MultipleFailureException extends Exception {
//     private static final long serialVersionUID = 1L;
// 
//     /*
//      * We have to use the f prefix until the next major release to ensure
//      * serialization compatibility. 
//      * See https://github.com/junit-team/junit4/issues/976
//      */
//     private final List<Throwable> fErrors;
// 
//     public MultipleFailureException(List<Throwable> errors) {
//         if (errors.isEmpty()) {
//             throw new IllegalArgumentException(
//                     "List of Throwables must not be empty");
//         }
//         this.fErrors = new ArrayList<Throwable>(errors.size());
//         for (Throwable error : errors) {
//             if (error instanceof AssumptionViolatedException) {
//                 error = new TestCouldNotBeSkippedException((AssumptionViolatedException) error);
//             }
//             fErrors.add(error);
//         }
//     }
// 
//     public List<Throwable> getFailures() {
//         return Collections.unmodifiableList(fErrors);
//     }
// 
//     @Override
//     public String getMessage() {
//         StringBuilder sb = new StringBuilder(
//                 String.format("There were %d errors:", fErrors.size()));
//         for (Throwable e : fErrors) {
//             sb.append(String.format("%n  %s(%s)", e.getClass().getName(), e.getMessage()));
//         }
//         return sb.toString();
//     }
// 
//     @Override
//     public void printStackTrace() {
//         for (Throwable e: fErrors) {
//             e.printStackTrace();
//         }
//     }
//     
//     @Override
//     public void printStackTrace(PrintStream s) {
//         for (Throwable e: fErrors) {
//             e.printStackTrace(s);
//         }
//     }
//     
//     @Override
//     public void printStackTrace(PrintWriter s) {
//         for (Throwable e: fErrors) {
//             e.printStackTrace(s);
//         }
//     }
//     
//     /**
//      * Asserts that a list of throwables is empty. If it isn't empty,
//      * will throw {@link MultipleFailureException} (if there are
//      * multiple throwables in the list) or the first element in the list
//      * (if there is only one element).
//      *
//      * @param errors list to check
//      * @throws Exception or Error if the list is not empty
//      */
//     @SuppressWarnings("deprecation")
//     public static void assertEmpty(List<Throwable> errors) throws Exception {
//         if (errors.isEmpty()) {
//             return;
//         }
//         if (errors.size() == 1) {
//             throw Throwables.rethrowAsException(errors.get(0));
//         }
// 
//         /*
//            * Many places in the code are documented to throw
//            * org.junit.internal.runners.model.MultipleFailureException.
//            * That class now extends this one, so we throw the internal
//            * exception in case developers have tests that catch
//            * MultipleFailureException.
//            */
//         throw new org.junit.internal.runners.model.MultipleFailureException(errors);
//     }
// }


// Path: src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.internal.management.ManagementFactory;
import org.junit.internal.management.ThreadMXBean;
import org.junit.runners.model.MultipleFailureException;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestTimedOutException;

    private Throwable getResult(FutureTask<Throwable> task, Thread thread) {
        try {
            if (timeout > 0) {
                return task.get(timeout, timeUnit);
            } else {
                return task.get();
            }
        } catch (InterruptedException e) {
            return e; // caller will re-throw; no need to call Thread.interrupt()
        } catch (ExecutionException e) {
            // test failed; have caller re-throw the exception thrown by the test
            return e.getCause();
        } catch (TimeoutException e) {
            return createTimeoutException(thread);
        }
    }

    private Exception createTimeoutException(Thread thread) {
        StackTraceElement[] stackTrace = thread.getStackTrace();
        final Thread stuckThread = lookForStuckThread ? getStuckThread(thread) : null;
        Exception currThreadException = new TestTimedOutException(timeout, timeUnit);
        if (stackTrace != null) {
            currThreadException.setStackTrace(stackTrace);
            thread.interrupt();
        }
        if (stuckThread != null) {
            Exception stuckThreadException = 
                new Exception("Appears to be stuck in thread " +
                               stuckThread.getName());
            stuckThreadException.setStackTrace(getStackTrace(stuckThread));
            return new MultipleFailureException(