// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableFunction.java
// @FunctionalInterface
// public interface SerializableFunction<T, R> extends Function<T, R>, Serializable {
// 	/**
// 	 * Returns a composed function that first applies the {@code before}
// 	 * function to its input, and then applies this function to the result.
// 	 * If evaluation of either function throws an exception, it is relayed to
// 	 * the caller of the composed function.
// 	 *
// 	 * @param <V> the type of input to the {@code before} function, and to the
// 	 *           composed function
// 	 * @param before the function to apply before this function is applied
// 	 * @return a composed function that first applies the {@code before}
// 	 * function and then applies this function
// 	 * @throws NullPointerException if before is null
// 	 *
// 	 * @see #andThen(Function)
// 	 */
// 	default <V> SerializableFunction<V, R> compose(SerializableFunction<? super V, ? extends T> before) {
// 		Objects.requireNonNull(before);
// 		return (V v) -> apply(before.apply(v));
// 	}
// 
// 	/**
// 	 * Returns a composed function that first applies this function to
// 	 * its input, and then applies the {@code after} function to the result.
// 	 * If evaluation of either function throws an exception, it is relayed to
// 	 * the caller of the composed function.
// 	 *
// 	 * @param <V> the type of output of the {@code after} function, and of the
// 	 *           composed function
// 	 * @param after the function to apply after this function is applied
// 	 * @return a composed function that first applies this function and then
// 	 * applies the {@code after} function
// 	 * @throws NullPointerException if after is null
// 	 *
// 	 * @see #compose(Function)
// 	 */
// 	default <V> SerializableFunction<T, V> andThen(SerializableFunction<? super R, ? extends V> after) {
// 		Objects.requireNonNull(after);
// 		return (T t) -> after.apply(apply(t));
// 	}
// 
// 	/**
// 	 * Returns a function that always returns its input argument.
// 	 *
// 	 * @param <T> the type of the input and output objects to the function
// 	 * @return a function that always returns its input argument
// 	 */
// 	static <T> SerializableFunction<T, T> identity() {
// 		return t -> t;
// 	}
// }
// 
// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableToDoubleFunction.java
// @FunctionalInterface
// public interface SerializableToDoubleFunction<T> extends ToDoubleFunction<T>, Serializable {
// 
// }
// 
// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableToIntFunction.java
// @FunctionalInterface
// public interface SerializableToIntFunction<T> extends ToIntFunction<T>, Serializable {
// 
// }
// 
// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableToLongFunction.java
// @FunctionalInterface
// public interface SerializableToLongFunction<T> extends ToLongFunction<T>, Serializable {
// 
// }


import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;
import org.danekja.java.util.function.serializable.SerializableFunction;
import org.danekja.java.util.function.serializable.SerializableToDoubleFunction;
import org.danekja.java.util.function.serializable.SerializableToIntFunction;
import org.danekja.java.util.function.serializable.SerializableToLongFunction;
	 *
	 * @param  keyExtractor the function used to extract the long sort key
	 * @return a lexicographic-order comparator composed of this and then the
	 *         {@code long} sort key
	 * @throws NullPointerException if the argument is null.
	 * @see #comparingLong(SerializableToLongFunction)
	 * @see #thenComparing(SerializableComparator)
	 * @since 1.8
	 */
    default SerializableComparator<T> thenComparingLong(
    		SerializableToLongFunction<? super T> keyExtractor) {
        return thenComparing(comparingLong(keyExtractor));
    }

	/**
	 * Returns a lexicographic-order comparator with a function that
	 * extracts a {@code double} sort key.
	 *
	 * @implSpec This default implementation behaves as if {@code
	 *           thenComparing(comparingDouble(keyExtractor))}.
	 *
	 * @param  keyExtractor the function used to extract the double sort key
	 * @return a lexicographic-order comparator composed of this and then the
	 *         {@code double} sort key
	 * @throws NullPointerException if the argument is null.
	 * @see #comparingDouble(SerializableToDoubleFunction)
	 * @see #thenComparing(SerializableComparator)
	 * @since 1.8
	 */
    default SerializableComparator<T> thenComparingDouble(
// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableFunction.java
// @FunctionalInterface
// public interface SerializableFunction<T, R> extends Function<T, R>, Serializable {
// 	/**
// 	 * Returns a composed function that first applies the {@code before}
// 	 * function to its input, and then applies this function to the result.
// 	 * If evaluation of either function throws an exception, it is relayed to
// 	 * the caller of the composed function.
// 	 *
// 	 * @param <V> the type of input to the {@code before} function, and to the
// 	 *           composed function
// 	 * @param before the function to apply before this function is applied
// 	 * @return a composed function that first applies the {@code before}
// 	 * function and then applies this function
// 	 * @throws NullPointerException if before is null
// 	 *
// 	 * @see #andThen(Function)
// 	 */
// 	default <V> SerializableFunction<V, R> compose(SerializableFunction<? super V, ? extends T> before) {
// 		Objects.requireNonNull(before);
// 		return (V v) -> apply(before.apply(v));
// 	}
// 
// 	/**
// 	 * Returns a composed function that first applies this function to
// 	 * its input, and then applies the {@code after} function to the result.
// 	 * If evaluation of either function throws an exception, it is relayed to
// 	 * the caller of the composed function.
// 	 *
// 	 * @param <V> the type of output of the {@code after} function, and of the
// 	 *           composed function
// 	 * @param after the function to apply after this function is applied
// 	 * @return a composed function that first applies this function and then
// 	 * applies the {@code after} function
// 	 * @throws NullPointerException if after is null
// 	 *
// 	 * @see #compose(Function)
// 	 */
// 	default <V> SerializableFunction<T, V> andThen(SerializableFunction<? super R, ? extends V> after) {
// 		Objects.requireNonNull(after);
// 		return (T t) -> after.apply(apply(t));
// 	}
// 
// 	/**
// 	 * Returns a function that always returns its input argument.
// 	 *
// 	 * @param <T> the type of the input and output objects to the function
// 	 * @return a function that always returns its input argument
// 	 */
// 	static <T> SerializableFunction<T, T> identity() {
// 		return t -> t;
// 	}
// }
// 
// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableToDoubleFunction.java
// @FunctionalInterface
// public interface SerializableToDoubleFunction<T> extends ToDoubleFunction<T>, Serializable {
// 
// }
// 
// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableToIntFunction.java
// @FunctionalInterface
// public interface SerializableToIntFunction<T> extends ToIntFunction<T>, Serializable {
// 
// }
// 
// Path: src/main/java/org/danekja/java/util/function/serializable/SerializableToLongFunction.java
// @FunctionalInterface
// public interface SerializableToLongFunction<T> extends ToLongFunction<T>, Serializable {
// 
// }


// Path: src/main/java/org/danekja/java/misc/serializable/SerializableComparator.java
import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;
import org.danekja.java.util.function.serializable.SerializableFunction;
import org.danekja.java.util.function.serializable.SerializableToDoubleFunction;
import org.danekja.java.util.function.serializable.SerializableToIntFunction;
import org.danekja.java.util.function.serializable.SerializableToLongFunction;

	 *
	 * @param  keyExtractor the function used to extract the long sort key
	 * @return a lexicographic-order comparator composed of this and then the
	 *         {@code long} sort key
	 * @throws NullPointerException if the argument is null.
	 * @see #comparingLong(SerializableToLongFunction)
	 * @see #thenComparing(SerializableComparator)
	 * @since 1.8
	 */
    default SerializableComparator<T> thenComparingLong(
    		SerializableToLongFunction<? super T> keyExtractor) {
        return thenComparing(comparingLong(keyExtractor));
    }

	/**
	 * Returns a lexicographic-order comparator with a function that
	 * extracts a {@code double} sort key.
	 *
	 * @implSpec This default implementation behaves as if {@code
	 *           thenComparing(comparingDouble(keyExtractor))}.
	 *
	 * @param  keyExtractor the function used to extract the double sort key
	 * @return a lexicographic-order comparator composed of this and then the
	 *         {@code double} sort key
	 * @throws NullPointerException if the argument is null.
	 * @see #comparingDouble(SerializableToDoubleFunction)
	 * @see #thenComparing(SerializableComparator)
	 * @since 1.8
	 */
    default SerializableComparator<T> thenComparingDouble(
    		SerializableToDoubleFunction<? super T> keyExtractor) {