All Downloads are FREE. Search and download functionalities are using the official Maven repository.

griffon.javafx.beans.binding.ReducingBindings Maven / Gradle / Ivy

/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright 2008-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package griffon.javafx.beans.binding;

import javafx.beans.binding.BooleanBinding;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.binding.FloatBinding;
import javafx.beans.binding.IntegerBinding;
import javafx.beans.binding.LongBinding;
import javafx.beans.binding.NumberBinding;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.binding.StringBinding;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.collections.ObservableSet;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;

import static java.util.Objects.requireNonNull;
import static javafx.beans.binding.Bindings.createBooleanBinding;
import static javafx.beans.binding.Bindings.createDoubleBinding;
import static javafx.beans.binding.Bindings.createFloatBinding;
import static javafx.beans.binding.Bindings.createIntegerBinding;
import static javafx.beans.binding.Bindings.createLongBinding;
import static javafx.beans.binding.Bindings.createObjectBinding;
import static javafx.beans.binding.Bindings.createStringBinding;

/**
 * @author Andres Almiray
 * @since 2.10.0
 */
public final class ReducingBindings {
    private static final String ERROR_ITEMS_NULL = "Argument 'items' must not be null";
    private static final String ERROR_MAPPER_NULL = "Argument 'mapper' must not be null";
    private static final String ERROR_REDUCER_NULL = "Argument 'reducer' must not be null";
    private static final String ERROR_SUPPLIER_NULL = "Argument 'supplier' must not be null";

    private ReducingBindings() {
        // prevent instantiation
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> items.values().stream().reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createObjectBinding(() -> items.values().stream().reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            return items.values().stream().reduce(operator).orElse(defaultValue);
        }, items, reducer);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            return items.values().stream().reduce(operator).orElseGet(supplier);
        }, items, reducer);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createBooleanBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createIntegerBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createLongBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createFloatBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a String binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a String binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a String binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a String binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createStringBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a String binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a String binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a String binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a String binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> items.stream().reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list.
     *
     * @param items    the observable list of elements.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createObjectBinding(() -> items.stream().reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            return items.stream().reduce(operator).orElse(defaultValue);
        }, items, reducer);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list.
     *
     * @param items    the observable list of elements.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            return items.stream().reduce(operator).orElseGet(supplier);
        }, items, reducer);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        final Function mapperValue = mapper != null ? mapper : String::valueOf;
        return createStringBinding(() -> mapperValue.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        final Function mapperValue = mapper != null ? mapper : String::valueOf;
        return createStringBinding(() -> mapperValue.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue() != null ? mapper.getValue() : String::valueOf;
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createStringBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue() != null ? mapper.getValue() : String::valueOf;
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createLongBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createBooleanBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue)).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier)).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> items.stream().reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set.
     *
     * @param items    the observable set of elements.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createObjectBinding(() -> items.stream().reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            return items.stream().reduce(operator).orElse(defaultValue);
        }, items, reducer);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set.
     *
     * @param items    the observable set of elements.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            return items.stream().reduce(operator).orElseGet(supplier);
        }, items, reducer);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        final Function mapperValue = mapper != null ? mapper : String::valueOf;
        return createStringBinding(() -> mapperValue.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        final Function mapperValue = mapper != null ? mapper : String::valueOf;
        return createStringBinding(() -> mapperValue.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue() != null ? mapper.getValue() : String::valueOf;
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding reduceThenMapToString(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createStringBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue() != null ? mapper.getValue() : String::valueOf;
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createIntegerBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding reduceThenMapToInteger(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createLongBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding reduceThenMapToLong(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createLongBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createFloatBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding reduceThenMapToFloat(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding reduceThenMapToDouble(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createBooleanBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding reduceThenMapToBoolean(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue)).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding reduceThenMapToNumber(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier)).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableList items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to the reduced value.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> mapper.apply(items.stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> mapper.apply(items.stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableSet items, @Nullable final T defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to the reduced value.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElse(defaultValue)), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final BinaryOperator reducer, @Nonnull final Function mapper) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> mapper.apply(items.values().stream().reduce(reducer).orElseGet(supplier)), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     * @param mapper       a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableMap items, @Nullable final V defaultValue, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElse(defaultValue));
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to the reduced value.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     * @param mapper   a non-interfering, stateless function to apply to the reduced value.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding reduceThenMap(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> reducer, @Nonnull final ObservableValue> mapper) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator operator = reducer.getValue();
            requireNonNull(operator, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return mapperValue.apply(items.values().stream().reduce(operator).orElseGet(supplier));
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableList items, @Nullable final R defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableList items, @Nullable final R defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableSet items, @Nullable final R defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createObjectBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableSet items, @Nullable final R defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableMap items, @Nullable final R defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableMap items, @Nullable final R defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns an object binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an object binding
     */
    @Nonnull
    public static  ObjectBinding mapThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createObjectBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableList items, @Nullable final Boolean defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableList items, @Nullable final Boolean defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableSet items, @Nullable final Boolean defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createBooleanBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableSet items, @Nullable final Boolean defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableMap items, @Nullable final Boolean defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableMap items, @Nullable final Boolean defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a boolean binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a boolean binding
     */
    @Nonnull
    public static  BooleanBinding mapToBooleanThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createBooleanBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableList items, @Nullable final Integer defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableList items, @Nullable final Integer defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableSet items, @Nullable final Integer defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createIntegerBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableSet items, @Nullable final Integer defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableMap items, @Nullable final Integer defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableMap items, @Nullable final Integer defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns an integer binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return an integer binding
     */
    @Nonnull
    public static  IntegerBinding mapToIntegerThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createIntegerBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableList items, @Nullable final Long defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableList items, @Nullable final Long defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableSet items, @Nullable final Long defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createLongBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableSet items, @Nullable final Long defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableMap items, @Nullable final Long defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableMap items, @Nullable final Long defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a long binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a long binding
     */
    @Nonnull
    public static  LongBinding mapToLongThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createLongBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableList items, @Nullable final Float defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableList items, @Nullable final Float defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableSet items, @Nullable final Float defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createFloatBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableSet items, @Nullable final Float defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableMap items, @Nullable final Float defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableMap items, @Nullable final Float defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a float binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a float binding
     */
    @Nonnull
    public static  FloatBinding mapToFloatThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createFloatBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableList items, @Nullable final Double defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableList items, @Nullable final Double defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableSet items, @Nullable final Double defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableSet items, @Nullable final Double defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableMap items, @Nullable final Double defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableMap items, @Nullable final Double defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a double binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a double binding
     */
    @Nonnull
    public static  DoubleBinding mapToDoubleThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableList items, @Nullable final Number defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableList items, @Nullable final Number defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableSet items, @Nullable final Number defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableSet items, @Nullable final Number defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableMap items, @Nullable final Number defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier).doubleValue(), items);
    }

    /**
     * Returns a number binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableMap items, @Nullable final Number defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a number binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a number binding
     */
    @Nonnull
    public static  NumberBinding mapToNumberThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createDoubleBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier).doubleValue();
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableList items, @Nullable final String defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable list of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableList items, @Nullable final String defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the list. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable list of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableList items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableSet items, @Nullable final String defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        return createStringBinding(() -> items.stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> items.stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items        the observable set of elements.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each element.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableSet items, @Nullable final String defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all elements in the set. The mapper function is applied to each element before reduction.
     *
     * @param items    the observable set of elements.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each element.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableSet items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableMap items, @Nullable final String defaultValue, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElse(defaultValue), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final Function mapper, @Nonnull final BinaryOperator reducer) {
        requireNonNull(items, ERROR_ITEMS_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> items.values().stream().map(mapper).reduce(reducer).orElseGet(supplier), items);
    }

    /**
     * Returns a string binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items        the observable map.
     * @param defaultValue the value to be returned if there is no value present, may be null.
     * @param mapper       a non-interfering, stateless function to apply to each value.
     * @param reducer      an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableMap items, @Nullable final String defaultValue, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElse(defaultValue);
        }, items, reducer, mapper);
    }

    /**
     * Returns a string binding whose value is the reduction of all values in the map. The mapper function is applied to each value before reduction.
     *
     * @param items    the observable map.
     * @param supplier a {@code Supplier} whose result is returned if no value is present.
     * @param mapper   a non-interfering, stateless function to apply to each value.
     * @param reducer  an associative, non-interfering, stateless function for combining two values.
     *
     * @return a string binding
     */
    @Nonnull
    public static  StringBinding mapToStringThenReduce(@Nonnull final ObservableMap items, @Nonnull final Supplier supplier, @Nonnull final ObservableValue> mapper, @Nonnull final ObservableValue> reducer) {
        requireNonNull(supplier, ERROR_SUPPLIER_NULL);
        requireNonNull(reducer, ERROR_REDUCER_NULL);
        requireNonNull(mapper, ERROR_MAPPER_NULL);
        return createStringBinding(() -> {
            BinaryOperator reducerValue = reducer.getValue();
            requireNonNull(reducerValue, ERROR_REDUCER_NULL);
            final Function mapperValue = mapper.getValue();
            requireNonNull(mapperValue, ERROR_MAPPER_NULL);
            return items.values().stream().map(mapperValue).reduce(reducerValue).orElseGet(supplier);
        }, items, reducer, mapper);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy