// Path: src/main/java/com/google/code/tempusfugit/temporal/Duration.java
// public class Duration implements Comparable<Duration> {
// 
//     private final Long value;
//     private final TimeUnit unit;
// 
//     private Duration(Long value, TimeUnit unit) {
//         this.value = value;
//         this.unit = unit;
//     }
// 
//     public static Duration seconds(long seconds) {
//         validate(seconds, TimeUnit.SECONDS);
//         return new Duration(seconds, TimeUnit.SECONDS);
//     }
// 
//     public static Duration millis(long millis) {
//         validate(millis, TimeUnit.MILLISECONDS);
//         return new Duration(millis, TimeUnit.MILLISECONDS);
//     }
// 
//     public static Duration minutes(long minutes) {
//         long seconds = minutes * 60;
//         validate(seconds,  TimeUnit.SECONDS);
//         return new Duration(seconds, TimeUnit.SECONDS);
//     }
// 
//     public static Duration hours(long hours) {
//         return minutes(hours * 60);
//     }
// 
//     public static Duration days(long days) {
//         return hours(days * 24);
//     }
// 
//     private static void validate(long value, TimeUnit unit) {
//         Duration duration = new Duration(value, unit);
//         if (duration.inMillis() == Long.MAX_VALUE)
//             throw new IllegalArgumentException();
//     }
// 
//     public long inMillis() {
//         return unit.toMillis(value);
//     }
// 
//     public long inSeconds() {
//         return unit.toSeconds(value);
//     }
// 
//     public long inMinutes() {
//         return unit.toSeconds(value) / 60;
//     }
// 
//     public long inHours() {
//         return inMinutes() / 60;
//     }
// 
//     public long inDays() {
//         return inHours() / 24;
//     }
// 
//     public Duration plus(Duration duration) {
//         return millis(duration.inMillis() + this.inMillis());
//     }
// 
//     public Duration minus(Duration duration) {
//         return millis(this.inMillis() - duration.inMillis());
//     }
// 
//     public Boolean greaterThan(Duration duration) {
//         return this.inMillis() > duration.inMillis();
//     }
// 
//     public Boolean lessThan(Duration duration) {
//         return this.inMillis() < duration.inMillis();
//     }
// 
//     @Override
//     public int hashCode() {
//         return new Long(unit.toMillis(value)).hashCode();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (o == null)
//             return false;
//         if (!(o.getClass().getName().equals(Duration.class.getName())))
//             return false;
//         Duration other = (Duration) o;
//         return other.unit.toMillis(other.value) == this.unit.toMillis(this.value);
//     }
// 
//     public String toString() {
//         return "Duration " + value + " " + unit;
//     }
// 
//     public int compareTo(Duration other) {
//         return ((Long)inMillis()).compareTo(other.inMillis());
//     }
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/concurrency/ExecutorServiceShutdown.java
// public static ExecutorServiceShutdown shutdown(ExecutorService executor) {
//     return new ExecutorServiceShutdown(executor);
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/temporal/Duration.java
// public static Duration millis(long millis) {
//     validate(millis, TimeUnit.MILLISECONDS);
//     return new Duration(millis, TimeUnit.MILLISECONDS);
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/temporal/Duration.java
// public static Duration seconds(long seconds) {
//     validate(seconds, TimeUnit.SECONDS);
//     return new Duration(seconds, TimeUnit.SECONDS);
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/temporal/Timeout.java
// public static Timeout timeout(Duration duration) {
//     return new Timeout(duration);
// }


import static com.google.code.tempusfugit.temporal.Duration.millis;
import static com.google.code.tempusfugit.temporal.Duration.seconds;
import static com.google.code.tempusfugit.temporal.Timeout.timeout;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import com.google.code.tempusfugit.temporal.Duration;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static com.google.code.tempusfugit.concurrency.ExecutorServiceShutdown.shutdown;

    @Test
    @Ignore
    public void awaitingTerminationIsInterruptedAvoidsNullReturnValue() throws InterruptedException {
        try {
            awaitTerminationWillBeInterrupted();
            assertThat(shutdown(executor).waitingForCompletion(TIMEOUT), is(false));
        } finally {
            Thread.interrupted();
        }
    }

    private void awaitTerminationWillBeInterrupted() throws InterruptedException {
        context.checking(new Expectations() {{
            allowing(executor).shutdown();
            oneOf(executor).awaitTermination(with(any(long.class)), with(any(TimeUnit.class))); will(throwException(new InterruptedException()));
        }});
    }

    @Test
    public void waitingForShutdownWithNullExecutorService() throws TimeoutException, InterruptedException {
        assertThat(shutdown(null).waitingForShutdown(timeout(millis(5))), is(false));
    }

    @Test
    public void waitingForShutdown() throws TimeoutException, InterruptedException {
        context.checking(new Expectations() {{
            oneOf(executor).shutdownNow();
            oneOf(executor).isShutdown(); will(returnValue(true));
        }});
// Path: src/main/java/com/google/code/tempusfugit/temporal/Duration.java
// public class Duration implements Comparable<Duration> {
// 
//     private final Long value;
//     private final TimeUnit unit;
// 
//     private Duration(Long value, TimeUnit unit) {
//         this.value = value;
//         this.unit = unit;
//     }
// 
//     public static Duration seconds(long seconds) {
//         validate(seconds, TimeUnit.SECONDS);
//         return new Duration(seconds, TimeUnit.SECONDS);
//     }
// 
//     public static Duration millis(long millis) {
//         validate(millis, TimeUnit.MILLISECONDS);
//         return new Duration(millis, TimeUnit.MILLISECONDS);
//     }
// 
//     public static Duration minutes(long minutes) {
//         long seconds = minutes * 60;
//         validate(seconds,  TimeUnit.SECONDS);
//         return new Duration(seconds, TimeUnit.SECONDS);
//     }
// 
//     public static Duration hours(long hours) {
//         return minutes(hours * 60);
//     }
// 
//     public static Duration days(long days) {
//         return hours(days * 24);
//     }
// 
//     private static void validate(long value, TimeUnit unit) {
//         Duration duration = new Duration(value, unit);
//         if (duration.inMillis() == Long.MAX_VALUE)
//             throw new IllegalArgumentException();
//     }
// 
//     public long inMillis() {
//         return unit.toMillis(value);
//     }
// 
//     public long inSeconds() {
//         return unit.toSeconds(value);
//     }
// 
//     public long inMinutes() {
//         return unit.toSeconds(value) / 60;
//     }
// 
//     public long inHours() {
//         return inMinutes() / 60;
//     }
// 
//     public long inDays() {
//         return inHours() / 24;
//     }
// 
//     public Duration plus(Duration duration) {
//         return millis(duration.inMillis() + this.inMillis());
//     }
// 
//     public Duration minus(Duration duration) {
//         return millis(this.inMillis() - duration.inMillis());
//     }
// 
//     public Boolean greaterThan(Duration duration) {
//         return this.inMillis() > duration.inMillis();
//     }
// 
//     public Boolean lessThan(Duration duration) {
//         return this.inMillis() < duration.inMillis();
//     }
// 
//     @Override
//     public int hashCode() {
//         return new Long(unit.toMillis(value)).hashCode();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (o == null)
//             return false;
//         if (!(o.getClass().getName().equals(Duration.class.getName())))
//             return false;
//         Duration other = (Duration) o;
//         return other.unit.toMillis(other.value) == this.unit.toMillis(this.value);
//     }
// 
//     public String toString() {
//         return "Duration " + value + " " + unit;
//     }
// 
//     public int compareTo(Duration other) {
//         return ((Long)inMillis()).compareTo(other.inMillis());
//     }
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/concurrency/ExecutorServiceShutdown.java
// public static ExecutorServiceShutdown shutdown(ExecutorService executor) {
//     return new ExecutorServiceShutdown(executor);
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/temporal/Duration.java
// public static Duration millis(long millis) {
//     validate(millis, TimeUnit.MILLISECONDS);
//     return new Duration(millis, TimeUnit.MILLISECONDS);
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/temporal/Duration.java
// public static Duration seconds(long seconds) {
//     validate(seconds, TimeUnit.SECONDS);
//     return new Duration(seconds, TimeUnit.SECONDS);
// }
// 
// Path: src/main/java/com/google/code/tempusfugit/temporal/Timeout.java
// public static Timeout timeout(Duration duration) {
//     return new Timeout(duration);
// }


// Path: src/test/java/com/google/code/tempusfugit/concurrency/ExecutorServiceShutdownTest.java
import static com.google.code.tempusfugit.temporal.Duration.millis;
import static com.google.code.tempusfugit.temporal.Duration.seconds;
import static com.google.code.tempusfugit.temporal.Timeout.timeout;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import com.google.code.tempusfugit.temporal.Duration;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static com.google.code.tempusfugit.concurrency.ExecutorServiceShutdown.shutdown;


    @Test
    @Ignore
    public void awaitingTerminationIsInterruptedAvoidsNullReturnValue() throws InterruptedException {
        try {
            awaitTerminationWillBeInterrupted();
            assertThat(shutdown(executor).waitingForCompletion(TIMEOUT), is(false));
        } finally {
            Thread.interrupted();
        }
    }

    private void awaitTerminationWillBeInterrupted() throws InterruptedException {
        context.checking(new Expectations() {{
            allowing(executor).shutdown();
            oneOf(executor).awaitTermination(with(any(long.class)), with(any(TimeUnit.class))); will(throwException(new InterruptedException()));
        }});
    }

    @Test
    public void waitingForShutdownWithNullExecutorService() throws TimeoutException, InterruptedException {
        assertThat(shutdown(null).waitingForShutdown(timeout(millis(5))), is(false));
    }

    @Test
    public void waitingForShutdown() throws TimeoutException, InterruptedException {
        context.checking(new Expectations() {{
            oneOf(executor).shutdownNow();
            oneOf(executor).isShutdown(); will(returnValue(true));
        }});
        assertThat(shutdown(executor).waitingForShutdown(timeout(millis(500))), is(true));