// Path: src/main/java/javafixes/collection/CollectionUtil.java
// @SafeVarargs
// public static <T> ArrayList<T> newList(T... values) {
//     ArrayList<T> list = new ArrayList<T>(values.length);
//     Collections.addAll(list, values);
//     return list;
// }
// 
// Path: src/test/java/javafixes/test/Random.java
//     @SafeVarargs
//     public static long randomLong(long from, long to, Function<Long, Boolean>... validityConditions) {
//         return generateValidValue(
// //                () -> new RandomDataGenerator().nextLong(from, to),
//                 () -> ThreadLocalRandom.current().nextLong(from, to) + (long) randomInt(0, 1),
//                 validityConditions
//         );
//     }


import org.junit.Test;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import static javafixes.collection.CollectionUtil.newList;
import static javafixes.test.Random.randomLong;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
    public void shouldInformShutdownAwareTasksThatShutdownHasBeenTriggered() throws InterruptedException {
        List<Consumer<Runner>> shutdownMethods = newList(
                Runner::shutdown,
                Runner::shutdownNow
        );
        List<ShutdownAwareRunCheck> shutdownAwareRunChecks = newList(
                (runner, startCheck, endCheck, wasShutdownInfoReceived) -> runner.run(shutdownInfo -> { //

                    startCheck.countDown();

                    while (!shutdownInfo.wasShutdownTriggered()) {
                        doSomethingThatTakesTime();
                    }
                    wasShutdownInfoReceived.set(shutdownInfo.wasShutdownTriggered());

                    endCheck.countDown();

                    return 0;
                }),
                (runner, startCheck, endCheck, wasShutdownInfoReceived) -> runner.run(shutdownInfo -> {

                    startCheck.countDown();

                    while (!shutdownInfo.wasShutdownTriggered()) {
                        doSomethingThatTakesTime();
                    }
                    wasShutdownInfoReceived.set(shutdownInfo.wasShutdownTriggered());

                    endCheck.countDown();
                }),
// Path: src/main/java/javafixes/collection/CollectionUtil.java
// @SafeVarargs
// public static <T> ArrayList<T> newList(T... values) {
//     ArrayList<T> list = new ArrayList<T>(values.length);
//     Collections.addAll(list, values);
//     return list;
// }
// 
// Path: src/test/java/javafixes/test/Random.java
//     @SafeVarargs
//     public static long randomLong(long from, long to, Function<Long, Boolean>... validityConditions) {
//         return generateValidValue(
// //                () -> new RandomDataGenerator().nextLong(from, to),
//                 () -> ThreadLocalRandom.current().nextLong(from, to) + (long) randomInt(0, 1),
//                 validityConditions
//         );
//     }


// Path: src/test/java/javafixes/concurrency/RunnerTest.java
import org.junit.Test;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import static javafixes.collection.CollectionUtil.newList;
import static javafixes.test.Random.randomLong;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

    public void shouldInformShutdownAwareTasksThatShutdownHasBeenTriggered() throws InterruptedException {
        List<Consumer<Runner>> shutdownMethods = newList(
                Runner::shutdown,
                Runner::shutdownNow
        );
        List<ShutdownAwareRunCheck> shutdownAwareRunChecks = newList(
                (runner, startCheck, endCheck, wasShutdownInfoReceived) -> runner.run(shutdownInfo -> { //

                    startCheck.countDown();

                    while (!shutdownInfo.wasShutdownTriggered()) {
                        doSomethingThatTakesTime();
                    }
                    wasShutdownInfoReceived.set(shutdownInfo.wasShutdownTriggered());

                    endCheck.countDown();

                    return 0;
                }),
                (runner, startCheck, endCheck, wasShutdownInfoReceived) -> runner.run(shutdownInfo -> {

                    startCheck.countDown();

                    while (!shutdownInfo.wasShutdownTriggered()) {
                        doSomethingThatTakesTime();
                    }
                    wasShutdownInfoReceived.set(shutdownInfo.wasShutdownTriggered());

                    endCheck.countDown();
                }),
                (runner, startCheck, endCheck, wasShutdownInfoReceived) -> runner.runIn(randomLong(100, 300), TimeUnit.MILLISECONDS, shutdownInfo -> { //