package stexfires.util.function;

import java.util.Objects;
import java.util.function.BinaryOperator;
import java.util.function.BooleanSupplier;

/**
 * Represents an operation upon two {@code boolean}-valued operands and producing an
 * {@code boolean}-valued result.   This is the primitive type specialization of
 * {@link java.util.function.BinaryOperator} for {@code boolean}.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #applyAsBoolean(boolean, boolean)}.
 *
 * @author Mathias Kalb
 * @see java.util.function.BinaryOperator
 * @see stexfires.util.function.BooleanUnaryOperator
 * @see java.util.function.IntBinaryOperator
 * @since 0.1
 */
@FunctionalInterface
public interface BooleanBinaryOperator {

    /**
     * Applies this operator to the given operands.
     *
     * @param first  the first operand
     * @param second the second operand
     * @return the operator result
     */
    boolean applyAsBoolean(boolean first, boolean second);

    /**
     * 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 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
     */
    default BooleanBinaryOperator andThen(BooleanUnaryOperator after) {
        Objects.requireNonNull(after);
        return (first, second) -> after.applyAsBoolean(applyAsBoolean(first, second));
    }

    default BinaryOperator<Boolean> asBinaryOperator() {
        return this::applyAsBoolean;
    }

    default BooleanUnaryOperator asBooleanUnaryOperator(boolean second) {
        return (first) -> applyAsBoolean(first, second);
    }

    static BooleanBinaryOperator constant(boolean constant) {
        return (first, second) -> constant;
    }

    static BooleanBinaryOperator supplier(BooleanSupplier supplier) {
        Objects.requireNonNull(supplier);
        return (first, second) -> supplier.getAsBoolean();
    }

    static BooleanBinaryOperator first() {
        return (first, second) -> first;
    }

    static BooleanBinaryOperator second() {
        return (first, second) -> second;
    }

    static BooleanBinaryOperator equals() {
        return (first, second) -> first == second;
    }

    static BooleanBinaryOperator AND() {
        return (first, second) -> first && second;
    }

    static BooleanBinaryOperator NAND() {
        return (first, second) -> !(first && second);
    }

    static BooleanBinaryOperator OR() {
        return (first, second) -> first || second;
    }

    static BooleanBinaryOperator NOR() {
        return (first, second) -> !(first || second);
    }

    static BooleanBinaryOperator XOR() {
        return (first, second) -> first != second;
    }

    static BooleanBinaryOperator XNOR() {
        return (first, second) -> first == second;
    }

}

@@ -137,16 +137,94 @@
 upplier;
+%0Aimport java.util.function.Predicate;%0Aimport java.util.function.UnaryOperator;
 %0A%0A/**%0A *
@@ -2072,32 +2072,290 @@
 second);%0A    %7D%0A%0A
+    default Predicate%3CBoolean%3E asPredicate(boolean second) %7B%0A        return (first) -%3E applyAsBoolean(first, second);%0A    %7D%0A%0A    default UnaryOperator%3CBoolean%3E asUnaryOperator(boolean second) %7B%0A        return (first) -%3E applyAsBoolean(first, second);%0A    %7D%0A%0A
     static Boole
@@ -2396,24 +2396,24 @@
 constant) %7B%0A
-
         retu
@@ -3006,32 +3006,81 @@
  second;%0A    %7D%0A%0A
+    @SuppressWarnings(%22SpellCheckingInspection%22)%0A
     static Boole
@@ -3457,32 +3457,81 @@
  second;%0A    %7D%0A%0A
+    @SuppressWarnings(%22SpellCheckingInspection%22)%0A
     static Boole

Add asPredicate and asUnaryOperator methods