// Path: core/src/main/java/com/github/phantomthief/util/ThrowableConsumer.java
// @FunctionalInterface
// public interface ThrowableConsumer<T, X extends Throwable> {
// 
//     void accept(T t) throws X;
// 
//     default ThrowableConsumer<T, X> andThen(ThrowableConsumer<? super T, X> after) {
//         requireNonNull(after);
//         return t -> {
//             accept(t);
//             after.accept(t);
//         };
//     }
// }
// 
// Path: core/src/main/java/com/github/phantomthief/util/ThrowableFunction.java
// @FunctionalInterface
// public interface ThrowableFunction<T, R, X extends Throwable> {
// 
//     static <T, X extends Throwable> ThrowableFunction<T, T, X> identity() {
//         return t -> t;
//     }
// 
//     R apply(T t) throws X;
// 
//     default <V> ThrowableFunction<V, R, X>
//             compose(ThrowableFunction<? super V, ? extends T, X> before) {
//         requireNonNull(before);
//         return (V v) -> apply(before.apply(v));
//     }
// 
//     default <V> ThrowableFunction<T, V, X>
//             andThen(ThrowableFunction<? super R, ? extends V, X> after) {
//         requireNonNull(after);
//         return (T t) -> after.apply(apply(t));
//     }
// }
// 
// Path: core/src/main/java/com/github/phantomthief/util/ThrowableRunnable.java
// @FunctionalInterface
// public interface ThrowableRunnable<X extends Throwable> {
// 
//     void run() throws X;
// }


import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly;
import static java.lang.System.nanoTime;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import java.time.Duration;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.Supplier;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.phantomthief.util.ThrowableConsumer;
import com.github.phantomthief.util.ThrowableFunction;
import com.github.phantomthief.util.ThrowableRunnable;
import com.google.common.util.concurrent.AbstractFuture;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.ExecutionError;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.common.util.concurrent.UncheckedTimeoutException;
            TimeoutListenableFuture<O> newResult = new TimeoutListenableFuture<>(result);
            for (ThrowableConsumer<TimeoutException, Exception> timeoutListener : ((TimeoutListenableFuture<I>) input)
                    .getTimeoutListeners()) {
                newResult.addTimeoutListener(timeoutListener);
            }
            return newResult;
        } else {
            return result;
        }
    }

    /**
     * 用于替换
     * {@link Futures#transformAsync(ListenableFuture, com.google.common.util.concurrent.AsyncFunction, Executor)}
     * <p>
     * 主要提供两个额外的功能:
     * 1. API使用jdk8
     * 2. 提供了 {@link TimeoutListenableFuture} 的支持（保持Listener不会丢）
     *
     * @param input 输入的Future
     * @param function 用于从输入的Future转换为输出Future结果类型的转换函数
     * @param executor 转换函数执行的Executor
     * @return 返回转换后的Future对象
     */
    public static <I, O> ListenableFuture<O> transformAsync(ListenableFuture<I> input,
            AsyncFunction<? super I, ? extends O> function,
            Executor executor) {
        ListenableFuture<O> result = Futures.transformAsync(input, function, executor);
        if (input instanceof TimeoutListenableFuture) {
            TimeoutListenableFuture<O> newResult = new TimeoutListenableFuture<>(result);
// Path: core/src/main/java/com/github/phantomthief/util/ThrowableConsumer.java
// @FunctionalInterface
// public interface ThrowableConsumer<T, X extends Throwable> {
// 
//     void accept(T t) throws X;
// 
//     default ThrowableConsumer<T, X> andThen(ThrowableConsumer<? super T, X> after) {
//         requireNonNull(after);
//         return t -> {
//             accept(t);
//             after.accept(t);
//         };
//     }
// }
// 
// Path: core/src/main/java/com/github/phantomthief/util/ThrowableFunction.java
// @FunctionalInterface
// public interface ThrowableFunction<T, R, X extends Throwable> {
// 
//     static <T, X extends Throwable> ThrowableFunction<T, T, X> identity() {
//         return t -> t;
//     }
// 
//     R apply(T t) throws X;
// 
//     default <V> ThrowableFunction<V, R, X>
//             compose(ThrowableFunction<? super V, ? extends T, X> before) {
//         requireNonNull(before);
//         return (V v) -> apply(before.apply(v));
//     }
// 
//     default <V> ThrowableFunction<T, V, X>
//             andThen(ThrowableFunction<? super R, ? extends V, X> after) {
//         requireNonNull(after);
//         return (T t) -> after.apply(apply(t));
//     }
// }
// 
// Path: core/src/main/java/com/github/phantomthief/util/ThrowableRunnable.java
// @FunctionalInterface
// public interface ThrowableRunnable<X extends Throwable> {
// 
//     void run() throws X;
// }


// Path: core/src/main/java/com/github/phantomthief/concurrent/MoreFutures.java
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly;
import static java.lang.System.nanoTime;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import java.time.Duration;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.Supplier;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.phantomthief.util.ThrowableConsumer;
import com.github.phantomthief.util.ThrowableFunction;
import com.github.phantomthief.util.ThrowableRunnable;
import com.google.common.util.concurrent.AbstractFuture;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.ExecutionError;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.common.util.concurrent.UncheckedTimeoutException;

            TimeoutListenableFuture<O> newResult = new TimeoutListenableFuture<>(result);
            for (ThrowableConsumer<TimeoutException, Exception> timeoutListener : ((TimeoutListenableFuture<I>) input)
                    .getTimeoutListeners()) {
                newResult.addTimeoutListener(timeoutListener);
            }
            return newResult;
        } else {
            return result;
        }
    }

    /**
     * 用于替换
     * {@link Futures#transformAsync(ListenableFuture, com.google.common.util.concurrent.AsyncFunction, Executor)}
     * <p>
     * 主要提供两个额外的功能:
     * 1. API使用jdk8
     * 2. 提供了 {@link TimeoutListenableFuture} 的支持（保持Listener不会丢）
     *
     * @param input 输入的Future
     * @param function 用于从输入的Future转换为输出Future结果类型的转换函数
     * @param executor 转换函数执行的Executor
     * @return 返回转换后的Future对象
     */
    public static <I, O> ListenableFuture<O> transformAsync(ListenableFuture<I> input,
            AsyncFunction<? super I, ? extends O> function,
            Executor executor) {
        ListenableFuture<O> result = Futures.transformAsync(input, function, executor);
        if (input instanceof TimeoutListenableFuture) {
            TimeoutListenableFuture<O> newResult = new TimeoutListenableFuture<>(result);
            for (ThrowableConsumer<TimeoutException, Exception> timeoutListener : ((TimeoutListenableFuture<I>) input)