MappingBindings.java
0001 /*
0002  * SPDX-License-Identifier: Apache-2.0
0003  *
0004  * Copyright 2008-2017 the original author or authors.
0005  *
0006  * Licensed under the Apache License, Version 2.0 (the "License");
0007  * you may not use this file except in compliance with the License.
0008  * You may obtain a copy of the License at
0009  *
0010  *     http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing, software
0013  * distributed under the License is distributed on an "AS IS" BASIS,
0014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015  * See the License for the specific language governing permissions and
0016  * limitations under the License.
0017  */
0018 package griffon.javafx.beans.binding;
0019 
0020 import javafx.beans.binding.BooleanBinding;
0021 import javafx.beans.binding.DoubleBinding;
0022 import javafx.beans.binding.FloatBinding;
0023 import javafx.beans.binding.IntegerBinding;
0024 import javafx.beans.binding.LongBinding;
0025 import javafx.beans.binding.ObjectBinding;
0026 import javafx.beans.binding.StringBinding;
0027 import javafx.beans.value.ObservableBooleanValue;
0028 import javafx.beans.value.ObservableDoubleValue;
0029 import javafx.beans.value.ObservableFloatValue;
0030 import javafx.beans.value.ObservableIntegerValue;
0031 import javafx.beans.value.ObservableLongValue;
0032 import javafx.beans.value.ObservableObjectValue;
0033 import javafx.beans.value.ObservableStringValue;
0034 import javafx.beans.value.ObservableValue;
0035 import javafx.collections.ObservableList;
0036 
0037 import javax.annotation.Nonnull;
0038 import javax.annotation.Nullable;
0039 import java.util.function.BiFunction;
0040 import java.util.function.Function;
0041 import java.util.function.Supplier;
0042 
0043 import static java.util.Objects.requireNonNull;
0044 import static javafx.beans.binding.Bindings.createBooleanBinding;
0045 import static javafx.beans.binding.Bindings.createDoubleBinding;
0046 import static javafx.beans.binding.Bindings.createFloatBinding;
0047 import static javafx.beans.binding.Bindings.createIntegerBinding;
0048 import static javafx.beans.binding.Bindings.createLongBinding;
0049 import static javafx.beans.binding.Bindings.createObjectBinding;
0050 import static javafx.beans.binding.Bindings.createStringBinding;
0051 
0052 /**
0053  @author Andres Almiray
0054  @since 2.10.0
0055  */
0056 public final class MappingBindings {
0057     private static final String ERROR_MAPPER_NULL = "Argument 'mapper' must not be null";
0058     private static final String ERROR_SUPPLIER_NULL = "Argument 'supplier' must not be null";
0059     private static final String ERROR_OBSERVABLE_NULL = "Argument 'observable' must not be null";
0060     private static final String ERROR_OBSERVABLE1_NULL = "Argument 'observable1' must not be null";
0061     private static final String ERROR_OBSERVABLE2_NULL = "Argument 'observable2' must not be null";
0062     private static final String ERROR_DEFAULT_VALUE_NULL = "Argument 'defaultValue' must not be null";
0063 
0064     private MappingBindings() {
0065         // prevent instantiation
0066     }
0067 
0068     /**
0069      * Converts an observable into an object binding.
0070      *
0071      @param observable the observable to be converted.
0072      @param mapper     a non-interfering, stateless function to apply to the observable value.
0073      *
0074      @return an object binding.
0075      *
0076      @since 2.11.0
0077      */
0078     @Nonnull
0079     public static <T, R> ObjectBinding<R> mapAsObject(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<T, R> mapper) {
0080         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0081         requireNonNull(mapper, ERROR_MAPPER_NULL);
0082         return createObjectBinding(() -> mapper.apply(observable.getValue()), observable);
0083     }
0084 
0085     /**
0086      * Converts an observable into an object binding.
0087      *
0088      @param observable the observable to be converted.
0089      @param mapper     a non-interfering, stateless function to apply to the observable value.
0090      *
0091      @return an object binding.
0092      *
0093      @since 2.11.0
0094      */
0095     @Nonnull
0096     public static <T, R> ObjectBinding<R> mapAsObject(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<T, R>> mapper) {
0097         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0098         requireNonNull(mapper, ERROR_MAPPER_NULL);
0099         return createObjectBinding(() -> {
0100             Function<? super T, R> mapperValue = mapper.getValue();
0101             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0102             return mapperValue.apply(observable.getValue());
0103         }, observable);
0104     }
0105 
0106     /**
0107      * Converts an observable into a boolean binding.
0108      *
0109      @param observable the observable to be converted.
0110      @param mapper     a non-interfering, stateless function to apply to the observable value.
0111      *
0112      @return a boolean binding.
0113      *
0114      @since 2.11.0
0115      */
0116     @Nonnull
0117     public static <T> BooleanBinding mapAsBoolean(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<T, Boolean> mapper) {
0118         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0119         requireNonNull(mapper, ERROR_MAPPER_NULL);
0120         return createBooleanBinding(() -> mapper.apply(observable.getValue()), observable);
0121     }
0122 
0123     /**
0124      * Converts an observable into a boolean binding.
0125      *
0126      @param observable the observable to be converted.
0127      @param mapper     a non-interfering, stateless function to apply to the observable value.
0128      *
0129      @return a boolean binding.
0130      *
0131      @since 2.11.0
0132      */
0133     @Nonnull
0134     public static <T> BooleanBinding mapAsBoolean(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<T, Boolean>> mapper) {
0135         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0136         requireNonNull(mapper, ERROR_MAPPER_NULL);
0137         return createBooleanBinding(() -> {
0138             Function<? super T, Boolean> mapperValue = mapper.getValue();
0139             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0140             return mapperValue.apply(observable.getValue());
0141         }, observable);
0142     }
0143 
0144     /**
0145      * Converts an observable into an integer binding.
0146      *
0147      @param observable the observable to be converted.
0148      @param mapper     a non-interfering, stateless function to apply to the observable value.
0149      *
0150      @return an integer binding.
0151      *
0152      @since 2.11.0
0153      */
0154     @Nonnull
0155     public static <T> IntegerBinding mapAsInteger(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<T, Integer> mapper) {
0156         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0157         requireNonNull(mapper, ERROR_MAPPER_NULL);
0158         return createIntegerBinding(() -> mapper.apply(observable.getValue()), observable);
0159     }
0160 
0161     /**
0162      * Converts an observable into an integer binding.
0163      *
0164      @param observable the observable to be converted.
0165      @param mapper     a non-interfering, stateless function to apply to the observable value.
0166      *
0167      @return an integer binding.
0168      *
0169      @since 2.11.0
0170      */
0171     @Nonnull
0172     public static <T> IntegerBinding mapAsInteger(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<T, Integer>> mapper) {
0173         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0174         requireNonNull(mapper, ERROR_MAPPER_NULL);
0175         return createIntegerBinding(() -> {
0176             Function<? super T, Integer> mapperValue = mapper.getValue();
0177             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0178             return mapperValue.apply(observable.getValue());
0179         }, observable);
0180     }
0181 
0182     /**
0183      * Converts an observable into a long binding.
0184      *
0185      @param observable the observable to be converted.
0186      @param mapper     a non-interfering, stateless function to apply to the observable value.
0187      *
0188      @return a long binding.
0189      *
0190      @since 2.11.0
0191      */
0192     @Nonnull
0193     public static <T> LongBinding mapAsLong(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<T, Long> mapper) {
0194         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0195         requireNonNull(mapper, ERROR_MAPPER_NULL);
0196         return createLongBinding(() -> mapper.apply(observable.getValue()), observable);
0197     }
0198 
0199     /**
0200      * Converts an observable into a long binding.
0201      *
0202      @param observable the observable to be converted.
0203      @param mapper     a non-interfering, stateless function to apply to the observable value.
0204      *
0205      @return a long binding.
0206      *
0207      @since 2.11.0
0208      */
0209     @Nonnull
0210     public static <T> LongBinding mapAsLong(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<T, Long>> mapper) {
0211         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0212         requireNonNull(mapper, ERROR_MAPPER_NULL);
0213         return createLongBinding(() -> {
0214             Function<? super T, Long> mapperValue = mapper.getValue();
0215             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0216             return mapperValue.apply(observable.getValue());
0217         }, observable);
0218     }
0219 
0220     /**
0221      * Converts an observable into a float binding.
0222      *
0223      @param observable the observable to be converted.
0224      @param mapper     a non-interfering, stateless function to apply to the observable value.
0225      *
0226      @return a float binding.
0227      *
0228      @since 2.11.0
0229      */
0230     @Nonnull
0231     public static <T> FloatBinding mapAsFloat(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<T, Float> mapper) {
0232         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0233         requireNonNull(mapper, ERROR_MAPPER_NULL);
0234         return createFloatBinding(() -> mapper.apply(observable.getValue()), observable);
0235     }
0236 
0237     /**
0238      * Converts an observable into a float binding.
0239      *
0240      @param observable the observable to be converted.
0241      @param mapper     a non-interfering, stateless function to apply to the observable value.
0242      *
0243      @return a float binding.
0244      *
0245      @since 2.11.0
0246      */
0247     @Nonnull
0248     public static <T> FloatBinding mapAsFloat(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<T, Float>> mapper) {
0249         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0250         requireNonNull(mapper, ERROR_MAPPER_NULL);
0251         return createFloatBinding(() -> {
0252             Function<? super T, Float> mapperValue = mapper.getValue();
0253             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0254             return mapperValue.apply(observable.getValue());
0255         }, observable);
0256     }
0257 
0258     /**
0259      * Converts an observable into a double binding.
0260      *
0261      @param observable the observable to be converted.
0262      @param mapper     a non-interfering, stateless function to apply to the observable value.
0263      *
0264      @return a double binding.
0265      *
0266      @since 2.11.0
0267      */
0268     @Nonnull
0269     public static <T> DoubleBinding mapAsDouble(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<T, Double> mapper) {
0270         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0271         requireNonNull(mapper, ERROR_MAPPER_NULL);
0272         return createDoubleBinding(() -> mapper.apply(observable.getValue()), observable);
0273     }
0274 
0275     /**
0276      * Converts an observable into a double binding.
0277      *
0278      @param observable the observable to be converted.
0279      @param mapper     a non-interfering, stateless function to apply to the observable value.
0280      *
0281      @return a double binding.
0282      *
0283      @since 2.11.0
0284      */
0285     @Nonnull
0286     public static <T> DoubleBinding mapAsDouble(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<T, Double>> mapper) {
0287         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0288         requireNonNull(mapper, ERROR_MAPPER_NULL);
0289         return createDoubleBinding(() -> {
0290             Function<? super T, Double> mapperValue = mapper.getValue();
0291             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0292             return mapperValue.apply(observable.getValue());
0293         }, observable);
0294     }
0295 
0296     /**
0297      * Converts an observable into a string binding.
0298      *
0299      @param observable the observable to be converted.
0300      @param mapper     a non-interfering, stateless function to apply to the observable value.
0301      *
0302      @return a string binding.
0303      *
0304      @since 2.11.0
0305      */
0306     @Nonnull
0307     public static <T> StringBinding mapAsString(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<T, String> mapper) {
0308         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0309         requireNonNull(mapper, ERROR_MAPPER_NULL);
0310         return createStringBinding(() -> mapper.apply(observable.getValue()), observable);
0311     }
0312 
0313     /**
0314      * Converts an observable into a string binding.
0315      *
0316      @param observable the observable to be converted.
0317      @param mapper     a non-interfering, stateless function to apply to the observable value.
0318      *
0319      @return a string binding.
0320      *
0321      @since 2.11.0
0322      */
0323     @Nonnull
0324     public static <T> StringBinding mapAsString(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<T, String>> mapper) {
0325         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0326         requireNonNull(mapper, ERROR_MAPPER_NULL);
0327         return createStringBinding(() -> {
0328             Function<? super T, String> mapperValue = mapper.getValue();
0329             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0330             return mapperValue.apply(observable.getValue());
0331         }, observable);
0332     }
0333 
0334     /**
0335      * Converts a string object observable value into an object binding.
0336      *
0337      @param observable the observable to be converted.
0338      *
0339      @return an object binding.
0340      */
0341     @Nonnull
0342     public static ObjectBinding<String> mapToObject(@Nonnull final ObservableStringValue observable) {
0343         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0344         return createObjectBinding(observable::get, observable);
0345     }
0346 
0347     /**
0348      * Converts a boolean object observable value into an object binding.
0349      *
0350      @param observable the observable to be converted.
0351      *
0352      @return an object binding.
0353      */
0354     @Nonnull
0355     public static ObjectBinding<Boolean> mapToObject(@Nonnull final ObservableBooleanValue observable) {
0356         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0357         return createObjectBinding(observable::get, observable);
0358     }
0359 
0360     /**
0361      * Converts a integer object observable value into an object binding.
0362      *
0363      @param observable the observable to be converted.
0364      *
0365      @return an object binding.
0366      */
0367     @Nonnull
0368     public static ObjectBinding<Integer> mapToObject(@Nonnull final ObservableIntegerValue observable) {
0369         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0370         return createObjectBinding(observable::get, observable);
0371     }
0372 
0373     /**
0374      * Converts a long object observable value into an object binding.
0375      *
0376      @param observable the observable to be converted.
0377      *
0378      @return an object binding.
0379      */
0380     @Nonnull
0381     public static ObjectBinding<Long> mapToObject(@Nonnull final ObservableLongValue observable) {
0382         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0383         return createObjectBinding(observable::get, observable);
0384     }
0385 
0386     /**
0387      * Converts a float object observable value into an object binding.
0388      *
0389      @param observable the observable to be converted.
0390      *
0391      @return an object binding.
0392      */
0393     @Nonnull
0394     public static ObjectBinding<Float> mapToObject(@Nonnull final ObservableFloatValue observable) {
0395         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0396         return createObjectBinding(observable::get, observable);
0397     }
0398 
0399     /**
0400      * Converts a double object observable value into an object binding.
0401      *
0402      @param observable the observable to be converted.
0403      *
0404      @return an object binding.
0405      */
0406     @Nonnull
0407     public static ObjectBinding<Double> mapToObject(@Nonnull final ObservableDoubleValue observable) {
0408         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0409         return createObjectBinding(observable::get, observable);
0410     }
0411 
0412     /**
0413      * Converts a boolean object observable value into a boolean binding.
0414      *
0415      @param observable the observable to be converted.
0416      *
0417      @return a boolean binding.
0418      */
0419     @Nonnull
0420     public static BooleanBinding mapToBoolean(@Nonnull final ObservableObjectValue<Boolean> observable) {
0421         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0422         return createBooleanBinding(observable::get, observable);
0423     }
0424 
0425     /**
0426      * Converts a integer object observable value into a integer binding.
0427      *
0428      @param observable the observable to be converted.
0429      *
0430      @return a integer binding.
0431      */
0432     @Nonnull
0433     public static IntegerBinding mapToInteger(@Nonnull final ObservableObjectValue<Integer> observable) {
0434         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0435         return createIntegerBinding(observable::get, observable);
0436     }
0437 
0438     /**
0439      * Converts a long object observable value into a long binding.
0440      *
0441      @param observable the observable to be converted.
0442      *
0443      @return a long binding.
0444      */
0445     @Nonnull
0446     public static LongBinding mapToLong(@Nonnull final ObservableObjectValue<Long> observable) {
0447         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0448         return createLongBinding(observable::get, observable);
0449     }
0450 
0451     /**
0452      * Converts a float object observable value into a float binding.
0453      *
0454      @param observable the observable to be converted.
0455      *
0456      @return a float binding.
0457      */
0458     @Nonnull
0459     public static FloatBinding mapToFloat(@Nonnull final ObservableObjectValue<Float> observable) {
0460         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0461         return createFloatBinding(observable::get, observable);
0462     }
0463 
0464     /**
0465      * Converts a double object observable value into a double binding.
0466      *
0467      @param observable the observable to be converted.
0468      *
0469      @return a double binding.
0470      */
0471     @Nonnull
0472     public static DoubleBinding mapToDouble(@Nonnull final ObservableObjectValue<Double> observable) {
0473         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0474         return createDoubleBinding(observable::get, observable);
0475     }
0476 
0477     /**
0478      * Converts a literal object observable value into a string binding.
0479      *
0480      @param observable the observable to be converted.
0481      *
0482      @return a string binding.
0483      */
0484     @Nonnull
0485     public static StringBinding mapToString(@Nonnull final ObservableObjectValue<String> observable) {
0486         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0487         return createStringBinding(observable::get, observable);
0488     }
0489 
0490     /**
0491      * Creates an observable list where all elements of the source list are mapped by the supplied function.
0492      *
0493      @param source the source list.
0494      @param mapper a non-interfering, stateless function to apply to the reduced value.
0495      *
0496      @return an observable list.
0497      */
0498     @Nonnull
0499     public static <S, T> ObservableList<T> mapList(@Nonnull final ObservableList<? super S> source, @Nonnull final Function<S, T> mapper) {
0500         return new griffon.javafx.support.MappingObservableList<>((ObservableList<? extends S>source, mapper);
0501     }
0502 
0503     /**
0504      * Creates an observable list where all elements of the source list are mapped by the supplied function.
0505      *
0506      @param source the source list.
0507      @param mapper a non-interfering, stateless function to apply to the reduced value.
0508      *
0509      @return an observable list.
0510      */
0511     @Nonnull
0512     public static <S, T> ObservableList<T> mapList(@Nonnull final ObservableList<S> source, @Nonnull final ObservableValue<Function<S, T>> mapper) {
0513         return new griffon.javafx.support.MappingObservableList<>(source, mapper);
0514     }
0515 
0516     /**
0517      * Creates an object binding containing the value of the mapper function applied to the source observable.
0518      *
0519      @param observable the source observable.
0520      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0521      *
0522      @return an object binding.
0523      */
0524     @Nonnull
0525     public static <T, R> ObjectBinding<R> mapObject(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<? super T, ? extends R> mapper) {
0526         return mapObject(observable, mapper, (Rnull);
0527     }
0528 
0529     /**
0530      * Creates an object binding containing the value of the mapper function applied to the source observable.
0531      *
0532      @param observable   the source observable.
0533      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0534      @param defaultValue the value to be returned if there is no value present, may be null.
0535      *
0536      @return an object binding.
0537      */
0538     @Nonnull
0539     public static <T, R> ObjectBinding<R> mapObject(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<? super T, ? extends R> mapper, @Nullable final R defaultValue) {
0540         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0541         requireNonNull(mapper, ERROR_MAPPER_NULL);
0542         return createObjectBinding(() -> {
0543             T sourceValue = observable.getValue();
0544             return sourceValue == null ? defaultValue : mapper.apply(sourceValue);
0545         }, observable);
0546     }
0547 
0548     /**
0549      * Creates an object binding containing the value of the mapper function applied to the source observable.
0550      *
0551      @param observable the source observable.
0552      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0553      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0554      *
0555      @return an object binding.
0556      */
0557     @Nonnull
0558     public static <T, R> ObjectBinding<R> mapObject(@Nonnull final ObservableValue<T> observable, @Nonnull final Function<? super T, ? extends R> mapper, @Nonnull final Supplier<R> supplier) {
0559         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0560         requireNonNull(mapper, ERROR_MAPPER_NULL);
0561         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0562         return createObjectBinding(() -> {
0563             T sourceValue = observable.getValue();
0564             return sourceValue == null ? supplier.get() : mapper.apply(sourceValue);
0565         }, observable);
0566     }
0567 
0568     /**
0569      * Creates an object binding containing the value of the mapper function applied to the source observable.
0570      *
0571      @param observable the source observable.
0572      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0573      *
0574      @return an object binding.
0575      */
0576     @Nonnull
0577     public static <T, R> ObjectBinding<R> mapObject(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<? super T, ? extends R>> mapper) {
0578         return mapObject(observable, mapper, (Rnull);
0579     }
0580 
0581     /**
0582      * Creates an object binding containing the value of the mapper function applied to the source observable.
0583      *
0584      @param observable   the source observable.
0585      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0586      @param defaultValue the value to be returned if there is no value present, may be null.
0587      *
0588      @return an object binding.
0589      */
0590     @Nonnull
0591     public static <T, R> ObjectBinding<R> mapObject(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<? super T, ? extends R>> mapper, @Nullable final R defaultValue) {
0592         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0593         requireNonNull(mapper, ERROR_MAPPER_NULL);
0594         return createObjectBinding(() -> {
0595             T sourceValue = observable.getValue();
0596             Function<? super T, ? extends R> mapperValue = mapper.getValue();
0597             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0598             return sourceValue == null ? defaultValue : mapperValue.apply(sourceValue);
0599         }, observable, mapper);
0600     }
0601 
0602     /**
0603      * Creates an object binding containing the value of the mapper function applied to the source observable.
0604      *
0605      @param observable the source observable.
0606      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0607      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0608      *
0609      @return an object binding.
0610      */
0611     @Nonnull
0612     public static <T, R> ObjectBinding<R> mapObject(@Nonnull final ObservableValue<T> observable, @Nonnull final ObservableValue<Function<? super T, ? extends R>> mapper, @Nonnull final Supplier<R> supplier) {
0613         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0614         requireNonNull(mapper, ERROR_MAPPER_NULL);
0615         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0616         return createObjectBinding(() -> {
0617             T sourceValue = observable.getValue();
0618             Function<? super T, ? extends R> mapperValue = mapper.getValue();
0619             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0620             return sourceValue == null ? supplier.get() : mapperValue.apply(sourceValue);
0621         }, observable, mapper);
0622     }
0623 
0624     /**
0625      * Creates a boolean binding containing the value of the mapper function applied to the source observable.
0626      *
0627      @param observable the source observable.
0628      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0629      *
0630      @return a boolean binding.
0631      */
0632     @Nonnull
0633     public static BooleanBinding mapBoolean(@Nonnull final ObservableValue<Boolean> observable, @Nonnull final Function<Boolean, Boolean> mapper) {
0634         return mapBoolean(observable, mapper, false);
0635     }
0636 
0637     /**
0638      * Creates a boolean binding containing the value of the mapper function applied to the source observable.
0639      *
0640      @param observable   the source observable.
0641      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0642      @param defaultValue the value to be returned if there is no value present, may be null.
0643      *
0644      @return a boolean binding.
0645      */
0646     @Nonnull
0647     public static BooleanBinding mapBoolean(@Nonnull final ObservableValue<Boolean> observable, @Nonnull final Function<Boolean, Boolean> mapper, @Nonnull final Boolean defaultValue) {
0648         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0649         requireNonNull(mapper, ERROR_MAPPER_NULL);
0650         return createBooleanBinding(() -> {
0651             Boolean sourceValue = observable.getValue();
0652             return sourceValue == null ? defaultValue : mapper.apply(sourceValue);
0653         }, observable);
0654     }
0655 
0656     /**
0657      * Creates a boolean binding containing the value of the mapper function applied to the source observable.
0658      *
0659      @param observable the source observable.
0660      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0661      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0662      *
0663      @return a boolean binding.
0664      */
0665     @Nonnull
0666     public static BooleanBinding mapBoolean(@Nonnull final ObservableValue<Boolean> observable, @Nonnull final Function<Boolean, Boolean> mapper, @Nonnull final Supplier<Boolean> supplier) {
0667         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0668         requireNonNull(mapper, ERROR_MAPPER_NULL);
0669         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0670         return createBooleanBinding(() -> {
0671             Boolean sourceValue = observable.getValue();
0672             return sourceValue == null ? supplier.get() : mapper.apply(sourceValue);
0673         }, observable);
0674     }
0675 
0676     /**
0677      * Creates a boolean binding containing the value of the mapper function applied to the source observable.
0678      *
0679      @param observable the source observable.
0680      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0681      *
0682      @return a boolean binding.
0683      */
0684     @Nonnull
0685     public static BooleanBinding mapBoolean(@Nonnull final ObservableValue<Boolean> observable, @Nonnull final ObservableValue<Function<Boolean, Boolean>> mapper) {
0686         return mapBoolean(observable, mapper, false);
0687     }
0688 
0689     /**
0690      * Creates a boolean binding containing the value of the mapper function applied to the source observable.
0691      *
0692      @param observable   the source observable.
0693      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0694      @param defaultValue the value to be returned if there is no value present, may be null.
0695      *
0696      @return a boolean binding.
0697      */
0698     @Nonnull
0699     public static BooleanBinding mapBoolean(@Nonnull final ObservableValue<Boolean> observable, @Nonnull final ObservableValue<Function<Boolean, Boolean>> mapper, @Nonnull final Boolean defaultValue) {
0700         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0701         requireNonNull(mapper, ERROR_MAPPER_NULL);
0702         return createBooleanBinding(() -> {
0703             Boolean sourceValue = observable.getValue();
0704             Function<Boolean, Boolean> mapperValue = mapper.getValue();
0705             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0706             return sourceValue == null ? defaultValue : mapperValue.apply(sourceValue);
0707         }, observable, mapper);
0708     }
0709 
0710     /**
0711      * Creates a boolean binding containing the value of the mapper function applied to the source observable.
0712      *
0713      @param observable the source observable.
0714      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0715      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0716      *
0717      @return a boolean binding.
0718      */
0719     @Nonnull
0720     public static BooleanBinding mapBoolean(@Nonnull final ObservableValue<Boolean> observable, @Nonnull final ObservableValue<Function<Boolean, Boolean>> mapper, @Nonnull final Supplier<Boolean> supplier) {
0721         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0722         requireNonNull(mapper, ERROR_MAPPER_NULL);
0723         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0724         return createBooleanBinding(() -> {
0725             Boolean sourceValue = observable.getValue();
0726             Function<Boolean, Boolean> mapperValue = mapper.getValue();
0727             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0728             return sourceValue == null ? supplier.get() : mapperValue.apply(sourceValue);
0729         }, observable, mapper);
0730     }
0731 
0732     /**
0733      * Creates an integer binding containing the value of the mapper function applied to the source observable.
0734      *
0735      @param observable the source observable.
0736      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0737      *
0738      @return an integer binding.
0739      */
0740     @Nonnull
0741     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<Integer> observable, @Nonnull final Function<Integer, Integer> mapper) {
0742         return mapInteger(observable, mapper, 0);
0743     }
0744 
0745     /**
0746      * Creates an integer binding containing the value of the mapper function applied to the source observable.
0747      *
0748      @param observable   the source observable.
0749      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0750      @param defaultValue the value to be returned if there is no value present, may be null.
0751      *
0752      @return an integer binding.
0753      */
0754     @Nonnull
0755     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<Integer> observable, @Nonnull final Function<Integer, Integer> mapper, @Nonnull final Integer defaultValue) {
0756         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0757         requireNonNull(mapper, ERROR_MAPPER_NULL);
0758         return createIntegerBinding(() -> {
0759             Integer sourceValue = observable.getValue();
0760             return sourceValue == null ? defaultValue : mapper.apply(sourceValue);
0761         }, observable);
0762     }
0763 
0764 
0765     /**
0766      * Creates an integer binding containing the value of the mapper function applied to the source observable.
0767      *
0768      @param observable the source observable.
0769      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0770      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0771      *
0772      @return an integer binding.
0773      */
0774     @Nonnull
0775     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<Integer> observable, @Nonnull final Function<Integer, Integer> mapper, @Nonnull final Supplier<Integer> supplier) {
0776         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0777         requireNonNull(mapper, ERROR_MAPPER_NULL);
0778         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0779         return createIntegerBinding(() -> {
0780             Integer sourceValue = observable.getValue();
0781             return sourceValue == null ? supplier.get() : mapper.apply(sourceValue);
0782         }, observable);
0783     }
0784 
0785     /**
0786      * Creates an integer binding containing the value of the mapper function applied to the source observable.
0787      *
0788      @param observable the source observable.
0789      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0790      *
0791      @return an integer binding.
0792      */
0793     @Nonnull
0794     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<Integer> observable, @Nonnull final ObservableValue<Function<Integer, Integer>> mapper) {
0795         return mapInteger(observable, mapper, 0);
0796     }
0797 
0798     /**
0799      * Creates an integer binding containing the value of the mapper function applied to the source observable.
0800      *
0801      @param observable   the source observable.
0802      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0803      @param defaultValue the value to be returned if there is no value present, may be null.
0804      *
0805      @return an integer binding.
0806      */
0807     @Nonnull
0808     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<Integer> observable, @Nonnull final ObservableValue<Function<Integer, Integer>> mapper, @Nonnull final Integer defaultValue) {
0809         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0810         requireNonNull(mapper, ERROR_MAPPER_NULL);
0811         return createIntegerBinding(() -> {
0812             Integer sourceValue = observable.getValue();
0813             Function<Integer, Integer> mapperValue = mapper.getValue();
0814             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0815             return sourceValue == null ? defaultValue : mapperValue.apply(sourceValue);
0816         }, observable, mapper);
0817     }
0818 
0819     /**
0820      * Creates an integer binding containing the value of the mapper function applied to the source observable.
0821      *
0822      @param observable the source observable.
0823      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0824      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0825      *
0826      @return an integer binding.
0827      */
0828     @Nonnull
0829     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<Integer> observable, @Nonnull final ObservableValue<Function<Integer, Integer>> mapper, @Nonnull final Supplier<Integer> supplier) {
0830         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0831         requireNonNull(mapper, ERROR_MAPPER_NULL);
0832         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0833         return createIntegerBinding(() -> {
0834             Integer sourceValue = observable.getValue();
0835             Function<Integer, Integer> mapperValue = mapper.getValue();
0836             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0837             return sourceValue == null ? supplier.get() : mapperValue.apply(sourceValue);
0838         }, observable, mapper);
0839     }
0840 
0841     /**
0842      * Creates a long binding containing the value of the mapper function applied to the source observable.
0843      *
0844      @param observable the source observable.
0845      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0846      *
0847      @return a long binding.
0848      */
0849     @Nonnull
0850     public static LongBinding mapLong(@Nonnull final ObservableValue<Long> observable, @Nonnull final Function<Long, Long> mapper) {
0851         return mapLong(observable, mapper, 0L);
0852     }
0853 
0854     /**
0855      * Creates a long binding containing the value of the mapper function applied to the source observable.
0856      *
0857      @param observable   the source observable.
0858      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0859      @param defaultValue the value to be returned if there is no value present, may be null.
0860      *
0861      @return a long binding.
0862      */
0863     @Nonnull
0864     public static LongBinding mapLong(@Nonnull final ObservableValue<Long> observable, @Nonnull final Function<Long, Long> mapper, @Nonnull final Long defaultValue) {
0865         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0866         requireNonNull(mapper, ERROR_MAPPER_NULL);
0867         return createLongBinding(() -> {
0868             Long sourceValue = observable.getValue();
0869             return sourceValue == null ? defaultValue : mapper.apply(sourceValue);
0870         }, observable);
0871     }
0872 
0873 
0874     /**
0875      * Creates a long binding containing the value of the mapper function applied to the source observable.
0876      *
0877      @param observable the source observable.
0878      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0879      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0880      *
0881      @return a long binding.
0882      */
0883     @Nonnull
0884     public static LongBinding mapLong(@Nonnull final ObservableValue<Long> observable, @Nonnull final Function<Long, Long> mapper, @Nonnull final Supplier<Long> supplier) {
0885         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0886         requireNonNull(mapper, ERROR_MAPPER_NULL);
0887         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0888         return createLongBinding(() -> {
0889             Long sourceValue = observable.getValue();
0890             return sourceValue == null ? supplier.get() : mapper.apply(sourceValue);
0891         }, observable);
0892     }
0893 
0894     /**
0895      * Creates a long binding containing the value of the mapper function applied to the source observable.
0896      *
0897      @param observable the source observable.
0898      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0899      *
0900      @return a long binding.
0901      */
0902     @Nonnull
0903     public static LongBinding mapLong(@Nonnull final ObservableValue<Long> observable, @Nonnull final ObservableValue<Function<Long, Long>> mapper) {
0904         return mapLong(observable, mapper, 0L);
0905     }
0906 
0907     /**
0908      * Creates a long binding containing the value of the mapper function applied to the source observable.
0909      *
0910      @param observable   the source observable.
0911      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0912      @param defaultValue the value to be returned if there is no value present, may be null.
0913      *
0914      @return a long binding.
0915      */
0916     @Nonnull
0917     public static LongBinding mapLong(@Nonnull final ObservableValue<Long> observable, @Nonnull final ObservableValue<Function<Long, Long>> mapper, @Nonnull final Long defaultValue) {
0918         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0919         requireNonNull(mapper, ERROR_MAPPER_NULL);
0920         return createLongBinding(() -> {
0921             Long sourceValue = observable.getValue();
0922             Function<Long, Long> mapperValue = mapper.getValue();
0923             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0924             return sourceValue == null ? defaultValue : mapperValue.apply(sourceValue);
0925         }, observable, mapper);
0926     }
0927 
0928     /**
0929      * Creates a long binding containing the value of the mapper function applied to the source observable.
0930      *
0931      @param observable the source observable.
0932      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0933      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0934      *
0935      @return a long binding.
0936      */
0937     @Nonnull
0938     public static LongBinding mapLong(@Nonnull final ObservableValue<Long> observable, @Nonnull final ObservableValue<Function<Long, Long>> mapper, @Nonnull final Supplier<Long> supplier) {
0939         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0940         requireNonNull(mapper, ERROR_MAPPER_NULL);
0941         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0942         return createLongBinding(() -> {
0943             Long sourceValue = observable.getValue();
0944             Function<Long, Long> mapperValue = mapper.getValue();
0945             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
0946             return sourceValue == null ? supplier.get() : mapperValue.apply(sourceValue);
0947         }, observable, mapper);
0948     }
0949 
0950     /**
0951      * Creates a float binding containing the value of the mapper function applied to the source observable.
0952      *
0953      @param observable the source observable.
0954      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0955      *
0956      @return a float binding.
0957      */
0958     @Nonnull
0959     public static FloatBinding mapFloat(@Nonnull final ObservableValue<Float> observable, @Nonnull final Function<Float, Float> mapper) {
0960         return mapFloat(observable, mapper, 0f);
0961     }
0962 
0963     /**
0964      * Creates a float binding containing the value of the mapper function applied to the source observable.
0965      *
0966      @param observable   the source observable.
0967      @param mapper       a non-interfering, stateless function to apply to the reduced value.
0968      @param defaultValue the value to be returned if there is no value present, may be null.
0969      *
0970      @return a float binding.
0971      */
0972     @Nonnull
0973     public static FloatBinding mapFloat(@Nonnull final ObservableValue<Float> observable, @Nonnull final Function<Float, Float> mapper, @Nonnull final Float defaultValue) {
0974         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0975         requireNonNull(mapper, ERROR_MAPPER_NULL);
0976         return createFloatBinding(() -> {
0977             Float sourceValue = observable.getValue();
0978             return sourceValue == null ? defaultValue : mapper.apply(sourceValue);
0979         }, observable);
0980     }
0981 
0982     /**
0983      * Creates a float binding containing the value of the mapper function applied to the source observable.
0984      *
0985      @param observable the source observable.
0986      @param mapper     a non-interfering, stateless function to apply to the reduced value.
0987      @param supplier   a {@code Supplier} whose result is returned if no value is present.
0988      *
0989      @return a float binding.
0990      */
0991     @Nonnull
0992     public static FloatBinding mapFloat(@Nonnull final ObservableValue<Float> observable, @Nonnull final Function<Float, Float> mapper, @Nonnull final Supplier<Float> supplier) {
0993         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
0994         requireNonNull(mapper, ERROR_MAPPER_NULL);
0995         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
0996         return createFloatBinding(() -> {
0997             Float sourceValue = observable.getValue();
0998             return sourceValue == null ? supplier.get() : mapper.apply(sourceValue);
0999         }, observable);
1000     }
1001 
1002     /**
1003      * Creates a float binding containing the value of the mapper function applied to the source observable.
1004      *
1005      @param observable the source observable.
1006      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1007      *
1008      @return a float binding.
1009      */
1010     @Nonnull
1011     public static FloatBinding mapFloat(@Nonnull final ObservableValue<Float> observable, @Nonnull final ObservableValue<Function<Float, Float>> mapper) {
1012         return mapFloat(observable, mapper, 0f);
1013     }
1014 
1015     /**
1016      * Creates a float binding containing the value of the mapper function applied to the source observable.
1017      *
1018      @param observable   the source observable.
1019      @param mapper       a non-interfering, stateless function to apply to the reduced value.
1020      @param defaultValue the value to be returned if there is no value present, may be null.
1021      *
1022      @return a float binding.
1023      */
1024     @Nonnull
1025     public static FloatBinding mapFloat(@Nonnull final ObservableValue<Float> observable, @Nonnull final ObservableValue<Function<Float, Float>> mapper, @Nullable final Float defaultValue) {
1026         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1027         requireNonNull(mapper, ERROR_MAPPER_NULL);
1028         return createFloatBinding(() -> {
1029             Float sourceValue = observable.getValue();
1030             Function<Float, Float> mapperValue = mapper.getValue();
1031             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1032             return sourceValue == null ? defaultValue : mapperValue.apply(sourceValue);
1033         }, observable, mapper);
1034     }
1035 
1036     /**
1037      * Creates a float binding containing the value of the mapper function applied to the source observable.
1038      *
1039      @param observable the source observable.
1040      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1041      @param supplier   a {@code Supplier} whose result is returned if no value is present.
1042      *
1043      @return a float binding.
1044      */
1045     @Nonnull
1046     public static FloatBinding mapFloat(@Nonnull final ObservableValue<Float> observable, @Nonnull final ObservableValue<Function<Float, Float>> mapper, @Nonnull final Supplier<Float> supplier) {
1047         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1048         requireNonNull(mapper, ERROR_MAPPER_NULL);
1049         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1050         return createFloatBinding(() -> {
1051             Float sourceValue = observable.getValue();
1052             Function<Float, Float> mapperValue = mapper.getValue();
1053             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1054             return sourceValue == null ? supplier.get() : mapperValue.apply(sourceValue);
1055         }, observable, mapper);
1056     }
1057 
1058     /**
1059      * Creates a double binding containing the value of the mapper function applied to the source observable.
1060      *
1061      @param observable the source observable.
1062      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1063      *
1064      @return a double binding.
1065      */
1066     @Nonnull
1067     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<Double> observable, @Nonnull final Function<Double, Double> mapper) {
1068         return mapDouble(observable, mapper, 0d);
1069     }
1070 
1071     /**
1072      * Creates a double binding containing the value of the mapper function applied to the source observable.
1073      *
1074      @param observable   the source observable.
1075      @param mapper       a non-interfering, stateless function to apply to the reduced value.
1076      @param defaultValue the value to be returned if there is no value present, may be null.
1077      *
1078      @return a double binding.
1079      */
1080     @Nonnull
1081     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<Double> observable, @Nonnull final Function<Double, Double> mapper, @Nullable final Double defaultValue) {
1082         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1083         requireNonNull(mapper, ERROR_MAPPER_NULL);
1084         return createDoubleBinding(() -> {
1085             Double sourceValue = observable.getValue();
1086             return sourceValue == null ? defaultValue : mapper.apply(sourceValue);
1087         }, observable);
1088     }
1089 
1090     /**
1091      * Creates a double binding containing the value of the mapper function applied to the source observable.
1092      *
1093      @param observable the source observable.
1094      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1095      @param supplier   a {@code Supplier} whose result is returned if no value is present.
1096      *
1097      @return a double binding.
1098      */
1099     @Nonnull
1100     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<Double> observable, @Nonnull final Function<Double, Double> mapper, @Nonnull final Supplier<Double> supplier) {
1101         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1102         requireNonNull(mapper, ERROR_MAPPER_NULL);
1103         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1104         return createDoubleBinding(() -> {
1105             Double sourceValue = observable.getValue();
1106             return sourceValue == null ? supplier.get() : mapper.apply(sourceValue);
1107         }, observable);
1108     }
1109 
1110     /**
1111      * Creates a double binding containing the value of the mapper function applied to the source observable.
1112      *
1113      @param observable the source observable.
1114      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1115      *
1116      @return a double binding.
1117      */
1118     @Nonnull
1119     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<Double> observable, @Nonnull final ObservableValue<Function<Double, Double>> mapper) {
1120         return mapDouble(observable, mapper, 0d);
1121     }
1122 
1123     /**
1124      * Creates a double binding containing the value of the mapper function applied to the source observable.
1125      *
1126      @param observable   the source observable.
1127      @param mapper       a non-interfering, stateless function to apply to the reduced value.
1128      @param defaultValue the value to be returned if there is no value present, may be null.
1129      *
1130      @return a double binding.
1131      */
1132     @Nonnull
1133     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<Double> observable, @Nonnull final ObservableValue<Function<Double, Double>> mapper, @Nonnull final Double defaultValue) {
1134         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1135         requireNonNull(mapper, ERROR_MAPPER_NULL);
1136         return createDoubleBinding(() -> {
1137             Double sourceValue = observable.getValue();
1138             Function<Double, Double> mapperValue = mapper.getValue();
1139             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1140             return sourceValue == null ? defaultValue : mapperValue.apply(sourceValue);
1141         }, observable, mapper);
1142     }
1143 
1144     /**
1145      * Creates a double binding containing the value of the mapper function applied to the source observable.
1146      *
1147      @param observable the source observable.
1148      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1149      @param supplier   a {@code Supplier} whose result is returned if no value is present.
1150      *
1151      @return a double binding.
1152      */
1153     @Nonnull
1154     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<Double> observable, @Nonnull final ObservableValue<Function<Double, Double>> mapper, @Nonnull final Supplier<Double> supplier) {
1155         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1156         requireNonNull(mapper, ERROR_MAPPER_NULL);
1157         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1158         return createDoubleBinding(() -> {
1159             Double sourceValue = observable.getValue();
1160             Function<Double, Double> mapperValue = mapper.getValue();
1161             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1162             return sourceValue == null ? supplier.get() : mapperValue.apply(sourceValue);
1163         }, observable, mapper);
1164     }
1165 
1166     /**
1167      * Creates a string binding containing the value of the mapper function applied to the source observable.
1168      *
1169      @param observable the source observable.
1170      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1171      *
1172      @return a string binding.
1173      */
1174     @Nonnull
1175     public static StringBinding mapString(@Nonnull final ObservableValue<String> observable, @Nonnull final Function<String, String> mapper) {
1176         return mapString(observable, mapper, "");
1177     }
1178 
1179     /**
1180      * Creates a string binding containing the value of the mapper function applied to the source observable.
1181      *
1182      @param observable   the source observable.
1183      @param mapper       a non-interfering, stateless function to apply to the reduced value.
1184      @param defaultValue the value to be returned if there is no value present, may be null.
1185      *
1186      @return a string binding.
1187      */
1188     @Nonnull
1189     public static StringBinding mapString(@Nonnull final ObservableValue<String> observable, @Nonnull final Function<String, String> mapper, @Nonnull final String defaultValue) {
1190         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1191         requireNonNull(mapper, ERROR_MAPPER_NULL);
1192         return createStringBinding(() -> {
1193             String sourceValue = observable.getValue();
1194             return sourceValue == null ? defaultValue : mapper.apply(sourceValue);
1195         }, observable);
1196     }
1197 
1198     /**
1199      * Creates a string binding containing the value of the mapper function applied to the source observable.
1200      *
1201      @param observable the source observable.
1202      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1203      @param supplier   a {@code Supplier} whose result is returned if no value is present.
1204      *
1205      @return a string binding.
1206      */
1207     @Nonnull
1208     public static StringBinding mapString(@Nonnull final ObservableValue<String> observable, @Nonnull final Function<String, String> mapper, @Nonnull final Supplier<String> supplier) {
1209         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1210         requireNonNull(mapper, ERROR_MAPPER_NULL);
1211         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1212         return createStringBinding(() -> {
1213             String sourceValue = observable.getValue();
1214             return sourceValue == null ? supplier.get() : mapper.apply(sourceValue);
1215         }, observable);
1216     }
1217 
1218     /**
1219      * Creates a string binding containing the value of the mapper function applied to the source observable.
1220      *
1221      @param observable the source observable.
1222      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1223      *
1224      @return a string binding.
1225      */
1226     @Nonnull
1227     public static StringBinding mapString(@Nonnull final ObservableValue<String> observable, @Nonnull final ObservableValue<Function<String, String>> mapper) {
1228         return mapString(observable, mapper, "");
1229     }
1230 
1231     /**
1232      * Creates a string binding containing the value of the mapper function applied to the source observable.
1233      *
1234      @param observable   the source observable.
1235      @param mapper       a non-interfering, stateless function to apply to the reduced value.
1236      @param defaultValue the value to be returned if there is no value present, may be null.
1237      *
1238      @return a string binding.
1239      */
1240     @Nonnull
1241     public static StringBinding mapString(@Nonnull final ObservableValue<String> observable, @Nonnull final ObservableValue<Function<String, String>> mapper, @Nonnull final String defaultValue) {
1242         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1243         requireNonNull(mapper, ERROR_MAPPER_NULL);
1244         return createStringBinding(() -> {
1245             String sourceValue = observable.getValue();
1246             Function<String, String> mapperValue = mapper.getValue();
1247             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1248             return sourceValue == null ? defaultValue : mapperValue.apply(sourceValue);
1249         }, observable, mapper);
1250     }
1251 
1252     /**
1253      * Creates a string binding containing the value of the mapper function applied to the source observable.
1254      *
1255      @param observable the source observable.
1256      @param mapper     a non-interfering, stateless function to apply to the reduced value.
1257      @param supplier   a {@code Supplier} whose result is returned if no value is present.
1258      *
1259      @return a string binding.
1260      */
1261     @Nonnull
1262     public static StringBinding mapString(@Nonnull final ObservableValue<String> observable, @Nonnull final ObservableValue<Function<String, String>> mapper, @Nonnull final Supplier<String> supplier) {
1263         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
1264         requireNonNull(mapper, ERROR_MAPPER_NULL);
1265         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1266         return createStringBinding(() -> {
1267             String sourceValue = observable.getValue();
1268             Function<String, String> mapperValue = mapper.getValue();
1269             requireNonNull(mapperValue, ERROR_MAPPER_NULL);
1270             return sourceValue == null ? supplier.get() : mapperValue.apply(sourceValue);
1271         }, observable, mapper);
1272     }
1273 
1274     /**
1275      * Returns a boolean binding whose value is the combination of two observable values.
1276      *
1277      @param observable1  the first observable value.
1278      @param observable2  the second observable value.
1279      @param defaultValue the value to be returned if there are no values present.
1280      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1281      *
1282      @return a boolean binding
1283      */
1284     @Nonnull
1285     public static BooleanBinding mapBooleans(@Nonnull final ObservableValue<Boolean> observable1, @Nonnull final ObservableValue<Boolean> observable2, @Nonnull final Boolean defaultValue, @Nonnull final BiFunction<Boolean, Boolean, Boolean> mapper) {
1286         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1287         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1288         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1289         requireNonNull(mapper, ERROR_MAPPER_NULL);
1290         return createBooleanBinding(() -> {
1291             Boolean value1 = observable1.getValue();
1292             Boolean value2 = observable2.getValue();
1293             if (value1 != null && value2 != null) {
1294                 return mapper.apply(value1, value2);
1295             }
1296             return defaultValue;
1297         }, observable1, observable2);
1298     }
1299 
1300     /**
1301      * Returns a boolean binding whose value is the combination of two observable values.
1302      *
1303      @param observable1 the first observable value.
1304      @param observable2 the second observable value.
1305      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1306      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1307      *
1308      @return a boolean binding
1309      */
1310     @Nonnull
1311     public static BooleanBinding mapBooleans(@Nonnull final ObservableValue<Boolean> observable1, @Nonnull final ObservableValue<Boolean> observable2, @Nonnull final Supplier<Boolean> supplier, @Nonnull final BiFunction<Boolean, Boolean, Boolean> mapper) {
1312         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1313         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1314         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1315         requireNonNull(mapper, ERROR_MAPPER_NULL);
1316         return createBooleanBinding(() -> {
1317             Boolean value1 = observable1.getValue();
1318             Boolean value2 = observable2.getValue();
1319             if (value1 != null && value2 != null) {
1320                 return mapper.apply(value1, value2);
1321             }
1322             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1323         }, observable1, observable2);
1324     }
1325 
1326     /**
1327      * Returns a boolean binding whose value is the combination of two observable values.
1328      *
1329      @param observable1  the first observable value.
1330      @param observable2  the second observable value.
1331      @param defaultValue the value to be returned if there is no value present.
1332      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1333      *
1334      @return a boolean binding
1335      */
1336     @Nonnull
1337     public static BooleanBinding mapBooleans(@Nonnull final ObservableValue<Boolean> observable1, @Nonnull final ObservableValue<Boolean> observable2, @Nonnull final Boolean defaultValue, @Nonnull final ObservableValue<BiFunction<Boolean, Boolean, Boolean>> mapper) {
1338         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1339         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1340         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1341         requireNonNull(mapper, ERROR_MAPPER_NULL);
1342         return createBooleanBinding(() -> {
1343             Boolean value1 = observable1.getValue();
1344             Boolean value2 = observable2.getValue();
1345             if (value1 != null && value2 != null) {
1346                 BiFunction<Boolean, Boolean, Boolean> function = mapper.getValue();
1347                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1348             }
1349             return defaultValue;
1350         }, observable1, observable2, mapper);
1351     }
1352 
1353     /**
1354      * Returns a boolean binding whose value is the combination of two observable values.
1355      *
1356      @param observable1 the first observable value.
1357      @param observable2 the second observable value.
1358      @param supplier    a {@code Supplier} whose result is returned if no value is present.
1359      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1360      *
1361      @return a boolean binding
1362      */
1363     @Nonnull
1364     public static BooleanBinding mapBooleans(@Nonnull final ObservableValue<Boolean> observable1, @Nonnull final ObservableValue<Boolean> observable2, @Nonnull final Supplier<Boolean> supplier, @Nonnull final ObservableValue<BiFunction<Boolean, Boolean, Boolean>> mapper) {
1365         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1366         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1367         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1368         requireNonNull(mapper, ERROR_MAPPER_NULL);
1369         return createBooleanBinding(() -> {
1370             Boolean value1 = observable1.getValue();
1371             Boolean value2 = observable2.getValue();
1372             if (value1 != null && value2 != null) {
1373                 BiFunction<Boolean, Boolean, Boolean> function = mapper.getValue();
1374                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1375             }
1376             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1377         }, observable1, observable2, mapper);
1378     }
1379 
1380     /**
1381      * Returns an integer binding whose value is the combination of two observable values.
1382      *
1383      @param observable1  the first observable value.
1384      @param observable2  the second observable value.
1385      @param defaultValue the value to be returned if there are no values present.
1386      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1387      *
1388      @return an integer binding
1389      */
1390     @Nonnull
1391     public static IntegerBinding mapIntegers(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Integer defaultValue, @Nonnull final BiFunction<? super Number, ? super Number, Integer> mapper) {
1392         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1393         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1394         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1395         requireNonNull(mapper, ERROR_MAPPER_NULL);
1396         return createIntegerBinding(() -> {
1397             Number value1 = observable1.getValue();
1398             Number value2 = observable2.getValue();
1399             if (value1 != null && value2 != null) {
1400                 return mapper.apply(value1, value2);
1401             }
1402             return defaultValue;
1403         }, observable1, observable2);
1404     }
1405 
1406     /**
1407      * Returns an integer binding whose value is the combination of two observable values.
1408      *
1409      @param observable1 the first observable value.
1410      @param observable2 the second observable value.
1411      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1412      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1413      *
1414      @return an integer binding
1415      */
1416     @Nonnull
1417     public static IntegerBinding mapIntegers(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Integer> supplier, @Nonnull final BiFunction<? super Number, ? super Number, Integer> mapper) {
1418         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1419         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1420         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1421         requireNonNull(mapper, ERROR_MAPPER_NULL);
1422         return createIntegerBinding(() -> {
1423             Number value1 = observable1.getValue();
1424             Number value2 = observable2.getValue();
1425             if (value1 != null && value2 != null) {
1426                 return mapper.apply(value1, value2);
1427             }
1428             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1429         }, observable1, observable2);
1430     }
1431 
1432     /**
1433      * Returns an integer binding whose value is the combination of two observable values.
1434      *
1435      @param observable1  the first observable value.
1436      @param observable2  the second observable value.
1437      @param defaultValue the value to be returned if there is no value present.
1438      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1439      *
1440      @return an integer binding
1441      */
1442     @Nonnull
1443     public static IntegerBinding mapIntegers(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Integer defaultValue, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Integer>> mapper) {
1444         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1445         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1446         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1447         requireNonNull(mapper, ERROR_MAPPER_NULL);
1448         return createIntegerBinding(() -> {
1449             Number value1 = observable1.getValue();
1450             Number value2 = observable2.getValue();
1451             if (value1 != null && value2 != null) {
1452                 BiFunction<? super Number, ? super Number, Integer> function = mapper.getValue();
1453                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1454             }
1455             return defaultValue;
1456         }, observable1, observable2, mapper);
1457     }
1458 
1459     /**
1460      * Returns an integer binding whose value is the combination of two observable values.
1461      *
1462      @param observable1 the first observable value.
1463      @param observable2 the second observable value.
1464      @param supplier    a {@code Supplier} whose result is returned if no value is present.
1465      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1466      *
1467      @return an integer binding
1468      */
1469     @Nonnull
1470     public static IntegerBinding mapIntegers(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Integer> supplier, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Integer>> mapper) {
1471         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1472         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1473         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1474         requireNonNull(mapper, ERROR_MAPPER_NULL);
1475         return createIntegerBinding(() -> {
1476             Number value1 = observable1.getValue();
1477             Number value2 = observable2.getValue();
1478             if (value1 != null && value2 != null) {
1479                 BiFunction<? super Number, ? super Number, Integer> function = mapper.getValue();
1480                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1481             }
1482             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1483         }, observable1, observable2, mapper);
1484     }
1485 
1486     /**
1487      * Returns a long binding whose value is the combination of two observable values.
1488      *
1489      @param observable1  the first observable value.
1490      @param observable2  the second observable value.
1491      @param defaultValue the value to be returned if there are no values present.
1492      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1493      *
1494      @return a long binding
1495      */
1496     @Nonnull
1497     public static LongBinding mapLongs(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Long defaultValue, @Nonnull final BiFunction<? super Number, ? super Number, Long> mapper) {
1498         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1499         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1500         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1501         requireNonNull(mapper, ERROR_MAPPER_NULL);
1502         return createLongBinding(() -> {
1503             Number value1 = observable1.getValue();
1504             Number value2 = observable2.getValue();
1505             if (value1 != null && value2 != null) {
1506                 return mapper.apply(value1, value2);
1507             }
1508             return defaultValue;
1509         }, observable1, observable2);
1510     }
1511 
1512     /**
1513      * Returns a long binding whose value is the combination of two observable values.
1514      *
1515      @param observable1 the first observable value.
1516      @param observable2 the second observable value.
1517      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1518      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1519      *
1520      @return a long binding
1521      */
1522     @Nonnull
1523     public static LongBinding mapLongs(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Long> supplier, @Nonnull final BiFunction<? super Number, ? super Number, Long> mapper) {
1524         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1525         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1526         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1527         requireNonNull(mapper, ERROR_MAPPER_NULL);
1528         return createLongBinding(() -> {
1529             Number value1 = observable1.getValue();
1530             Number value2 = observable2.getValue();
1531             if (value1 != null && value2 != null) {
1532                 return mapper.apply(value1, value2);
1533             }
1534             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1535         }, observable1, observable2);
1536     }
1537 
1538     /**
1539      * Returns a long binding whose value is the combination of two observable values.
1540      *
1541      @param observable1  the first observable value.
1542      @param observable2  the second observable value.
1543      @param defaultValue the value to be returned if there is no value present.
1544      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1545      *
1546      @return a long binding
1547      */
1548     @Nonnull
1549     public static LongBinding mapLongs(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Long defaultValue, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Long>> mapper) {
1550         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1551         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1552         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1553         requireNonNull(mapper, ERROR_MAPPER_NULL);
1554         return createLongBinding(() -> {
1555             Number value1 = observable1.getValue();
1556             Number value2 = observable2.getValue();
1557             if (value1 != null && value2 != null) {
1558                 BiFunction<? super Number, ? super Number, Long> function = mapper.getValue();
1559                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1560             }
1561             return defaultValue;
1562         }, observable1, observable2, mapper);
1563     }
1564 
1565     /**
1566      * Returns a long binding whose value is the combination of two observable values.
1567      *
1568      @param observable1 the first observable value.
1569      @param observable2 the second observable value.
1570      @param supplier    a {@code Supplier} whose result is returned if no value is present.
1571      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1572      *
1573      @return a long binding
1574      */
1575     @Nonnull
1576     public static LongBinding mapLongs(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Long> supplier, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Long>> mapper) {
1577         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1578         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1579         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1580         requireNonNull(mapper, ERROR_MAPPER_NULL);
1581         return createLongBinding(() -> {
1582             Number value1 = observable1.getValue();
1583             Number value2 = observable2.getValue();
1584             if (value1 != null && value2 != null) {
1585                 BiFunction<? super Number, ? super Number, Long> function = mapper.getValue();
1586                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1587             }
1588             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1589         }, observable1, observable2, mapper);
1590     }
1591 
1592     /**
1593      * Returns a float binding whose value is the combination of two observable values.
1594      *
1595      @param observable1  the first observable value.
1596      @param observable2  the second observable value.
1597      @param defaultValue the value to be returned if there are no values present.
1598      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1599      *
1600      @return a float binding
1601      */
1602     @Nonnull
1603     public static FloatBinding mapFloats(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Float defaultValue, @Nonnull final BiFunction<? super Number, ? super Number, Float> mapper) {
1604         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1605         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1606         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1607         requireNonNull(mapper, ERROR_MAPPER_NULL);
1608         return createFloatBinding(() -> {
1609             Number value1 = observable1.getValue();
1610             Number value2 = observable2.getValue();
1611             if (value1 != null && value2 != null) {
1612                 return mapper.apply(value1, value2);
1613             }
1614             return defaultValue;
1615         }, observable1, observable2);
1616     }
1617 
1618     /**
1619      * Returns a float binding whose value is the combination of two observable values.
1620      *
1621      @param observable1 the first observable value.
1622      @param observable2 the second observable value.
1623      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1624      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1625      *
1626      @return a float binding
1627      */
1628     @Nonnull
1629     public static FloatBinding mapFloats(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Float> supplier, @Nonnull final BiFunction<? super Number, ? super Number, Float> mapper) {
1630         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1631         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1632         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1633         requireNonNull(mapper, ERROR_MAPPER_NULL);
1634         return createFloatBinding(() -> {
1635             Number value1 = observable1.getValue();
1636             Number value2 = observable2.getValue();
1637             if (value1 != null && value2 != null) {
1638                 return mapper.apply(value1, value2);
1639             }
1640             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1641         }, observable1, observable2);
1642     }
1643 
1644     /**
1645      * Returns a float binding whose value is the combination of two observable values.
1646      *
1647      @param observable1  the first observable value.
1648      @param observable2  the second observable value.
1649      @param defaultValue the value to be returned if there is no value present.
1650      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1651      *
1652      @return a float binding
1653      */
1654     @Nonnull
1655     public static FloatBinding mapFloats(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Float defaultValue, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Float>> mapper) {
1656         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1657         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1658         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1659         requireNonNull(mapper, ERROR_MAPPER_NULL);
1660         return createFloatBinding(() -> {
1661             Number value1 = observable1.getValue();
1662             Number value2 = observable2.getValue();
1663             if (value1 != null && value2 != null) {
1664                 BiFunction<? super Number, ? super Number, Float> function = mapper.getValue();
1665                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1666             }
1667             return defaultValue;
1668         }, observable1, observable2, mapper);
1669     }
1670 
1671     /**
1672      * Returns a float binding whose value is the combination of two observable values.
1673      *
1674      @param observable1 the first observable value.
1675      @param observable2 the second observable value.
1676      @param supplier    a {@code Supplier} whose result is returned if no value is present.
1677      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1678      *
1679      @return a float binding
1680      */
1681     @Nonnull
1682     public static FloatBinding mapFloats(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Float> supplier, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Float>> mapper) {
1683         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1684         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1685         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1686         requireNonNull(mapper, ERROR_MAPPER_NULL);
1687         return createFloatBinding(() -> {
1688             Number value1 = observable1.getValue();
1689             Number value2 = observable2.getValue();
1690             if (value1 != null && value2 != null) {
1691                 BiFunction<? super Number, ? super Number, Float> function = mapper.getValue();
1692                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1693             }
1694             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1695         }, observable1, observable2, mapper);
1696     }
1697 
1698     /**
1699      * Returns a double binding whose value is the combination of two observable values.
1700      *
1701      @param observable1  the first observable value.
1702      @param observable2  the second observable value.
1703      @param defaultValue the value to be returned if there are no values present.
1704      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1705      *
1706      @return a double binding
1707      */
1708     @Nonnull
1709     public static DoubleBinding mapDoubles(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Double defaultValue, @Nonnull final BiFunction<? super Number, ? super Number, Double> mapper) {
1710         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1711         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1712         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1713         requireNonNull(mapper, ERROR_MAPPER_NULL);
1714         return createDoubleBinding(() -> {
1715             Number value1 = observable1.getValue();
1716             Number value2 = observable2.getValue();
1717             if (value1 != null && value2 != null) {
1718                 return mapper.apply(value1, value2);
1719             }
1720             return defaultValue;
1721         }, observable1, observable2);
1722     }
1723 
1724     /**
1725      * Returns a double binding whose value is the combination of two observable values.
1726      *
1727      @param observable1 the first observable value.
1728      @param observable2 the second observable value.
1729      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1730      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1731      *
1732      @return a double binding
1733      */
1734     @Nonnull
1735     public static DoubleBinding mapDoubles(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Double> supplier, @Nonnull final BiFunction<? super Number, ? super Number, Double> mapper) {
1736         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1737         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1738         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1739         requireNonNull(mapper, ERROR_MAPPER_NULL);
1740         return createDoubleBinding(() -> {
1741             Number value1 = observable1.getValue();
1742             Number value2 = observable2.getValue();
1743             if (value1 != null && value2 != null) {
1744                 return mapper.apply(value1, value2);
1745             }
1746             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1747         }, observable1, observable2);
1748     }
1749 
1750     /**
1751      * Returns a double binding whose value is the combination of two observable values.
1752      *
1753      @param observable1  the first observable value.
1754      @param observable2  the second observable value.
1755      @param defaultValue the value to be returned if there is no value present.
1756      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1757      *
1758      @return a double binding
1759      */
1760     @Nonnull
1761     public static DoubleBinding mapDoubles(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Double defaultValue, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Double>> mapper) {
1762         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1763         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1764         requireNonNull(defaultValue, ERROR_DEFAULT_VALUE_NULL);
1765         requireNonNull(mapper, ERROR_MAPPER_NULL);
1766         return createDoubleBinding(() -> {
1767             Number value1 = observable1.getValue();
1768             Number value2 = observable2.getValue();
1769             if (value1 != null && value2 != null) {
1770                 BiFunction<? super Number, ? super Number, Double> function = mapper.getValue();
1771                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1772             }
1773             return defaultValue;
1774         }, observable1, observable2, mapper);
1775     }
1776 
1777     /**
1778      * Returns a double binding whose value is the combination of two observable values.
1779      *
1780      @param observable1 the first observable value.
1781      @param observable2 the second observable value.
1782      @param supplier    a {@code Supplier} whose result is returned if no value is present.
1783      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1784      *
1785      @return a double binding
1786      */
1787     @Nonnull
1788     public static DoubleBinding mapDoubles(@Nonnull final ObservableValue<? extends Number> observable1, @Nonnull final ObservableValue<? extends Number> observable2, @Nonnull final Supplier<Double> supplier, @Nonnull final ObservableValue<BiFunction<? super Number, ? super Number, Double>> mapper) {
1789         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1790         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1791         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1792         requireNonNull(mapper, ERROR_MAPPER_NULL);
1793         return createDoubleBinding(() -> {
1794             Number value1 = observable1.getValue();
1795             Number value2 = observable2.getValue();
1796             if (value1 != null && value2 != null) {
1797                 BiFunction<? super Number, ? super Number, Double> function = mapper.getValue();
1798                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1799             }
1800             return requireNonNull(supplier.get(), ERROR_DEFAULT_VALUE_NULL);
1801         }, observable1, observable2, mapper);
1802     }
1803 
1804     /**
1805      * Returns an object binding whose value is the combination of two observable values.
1806      *
1807      @param observable1  the first observable value.
1808      @param observable2  the second observable value.
1809      @param defaultValue the value to be returned if there are no values present, may be null.
1810      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1811      *
1812      @return an object binding
1813      */
1814     @Nonnull
1815     public static <A, B, R> ObjectBinding<R> mapObjects(@Nonnull final ObservableValue<A> observable1, @Nonnull final ObservableValue<B> observable2, @Nullable final R defaultValue, @Nonnull final BiFunction<? super A, ? super B, R> mapper) {
1816         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1817         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1818         requireNonNull(mapper, ERROR_MAPPER_NULL);
1819         return createObjectBinding(() -> {
1820             A value1 = observable1.getValue();
1821             B value2 = observable2.getValue();
1822             if (value1 != null && value2 != null) {
1823                 return mapper.apply(value1, value2);
1824             }
1825             return defaultValue;
1826         }, observable1, observable2);
1827     }
1828 
1829     /**
1830      * Returns an object binding whose value is the combination of two observable values.
1831      *
1832      @param observable1 the first observable value.
1833      @param observable2 the second observable value.
1834      @param supplier    a {@code Supplier} whose result is returnedif no values are present.
1835      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1836      *
1837      @return an object binding
1838      */
1839     @Nonnull
1840     public static <A, B, R> ObjectBinding<R> mapObjects(@Nonnull final ObservableValue<A> observable1, @Nonnull final ObservableValue<B> observable2, @Nonnull final Supplier<R> supplier, @Nonnull final BiFunction<? super A, ? super B, R> mapper) {
1841         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1842         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1843         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1844         requireNonNull(mapper, ERROR_MAPPER_NULL);
1845         return createObjectBinding(() -> {
1846             A value1 = observable1.getValue();
1847             B value2 = observable2.getValue();
1848             if (value1 != null && value2 != null) {
1849                 return mapper.apply(value1, value2);
1850             }
1851             return supplier.get();
1852         }, observable1, observable2);
1853     }
1854 
1855     /**
1856      * Returns an object binding whose value is the combination of two observable values.
1857      *
1858      @param observable1  the first observable value.
1859      @param observable2  the second observable value.
1860      @param defaultValue the value to be returned if there is no value present, may be null.
1861      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1862      *
1863      @return an object binding
1864      */
1865     @Nonnull
1866     public static <A, B, R> ObjectBinding<R> mapObjects(@Nonnull final ObservableValue<A> observable1, @Nonnull final ObservableValue<B> observable2, @Nullable final R defaultValue, @Nonnull final ObservableValue<BiFunction<? super A, ? super B, R>> mapper) {
1867         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1868         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1869         requireNonNull(mapper, ERROR_MAPPER_NULL);
1870         return createObjectBinding(() -> {
1871             A value1 = observable1.getValue();
1872             B value2 = observable2.getValue();
1873             if (value1 != null && value2 != null) {
1874                 BiFunction<? super A, ? super B, R> function = mapper.getValue();
1875                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1876             }
1877             return defaultValue;
1878         }, observable1, observable2, mapper);
1879     }
1880 
1881     /**
1882      * Returns an object binding whose value is the combination of two observable values.
1883      *
1884      @param observable1 the first observable value.
1885      @param observable2 the second observable value.
1886      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1887      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1888      *
1889      @return an object binding
1890      */
1891     @Nonnull
1892     public static <A, B, R> ObjectBinding<R> mapObjects(@Nonnull final ObservableValue<A> observable1, @Nonnull final ObservableValue<B> observable2, @Nonnull final Supplier<R> supplier, @Nonnull final ObservableValue<BiFunction<? super A, ? super B, R>> mapper) {
1893         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1894         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1895         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1896         requireNonNull(mapper, ERROR_MAPPER_NULL);
1897         return createObjectBinding(() -> {
1898             A value1 = observable1.getValue();
1899             B value2 = observable2.getValue();
1900             if (value1 != null && value2 != null) {
1901                 BiFunction<? super A, ? super B, R> function = mapper.getValue();
1902                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1903             }
1904             return supplier.get();
1905         }, observable1, observable2, mapper);
1906     }
1907 
1908     /**
1909      * Returns a string binding whose value is the combination of two observable values.
1910      *
1911      @param observable1  the first observable value.
1912      @param observable2  the second observable value.
1913      @param defaultValue the value to be returned if there are no values present.
1914      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1915      *
1916      @return a string binding
1917      */
1918     @Nonnull
1919     public static StringBinding mapStrings(@Nonnull final ObservableValue<String> observable1, @Nonnull final ObservableValue<String> observable2, @Nullable final String defaultValue, @Nonnull final BiFunction<String, String, String> mapper) {
1920         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1921         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1922         requireNonNull(mapper, ERROR_MAPPER_NULL);
1923         return createStringBinding(() -> {
1924             String value1 = observable1.getValue();
1925             String value2 = observable2.getValue();
1926             if (value1 != null && value2 != null) {
1927                 return mapper.apply(value1, value2);
1928             }
1929             return defaultValue;
1930         }, observable1, observable2);
1931     }
1932 
1933     /**
1934      * Returns a string binding whose value is the combination of two observable values.
1935      *
1936      @param observable1 the first observable value.
1937      @param observable2 the second observable value.
1938      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1939      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1940      *
1941      @return a string binding
1942      */
1943     @Nonnull
1944     public static StringBinding mapStrings(@Nonnull final ObservableValue<String> observable1, @Nonnull final ObservableValue<String> observable2, @Nonnull final Supplier<String> supplier, @Nonnull final BiFunction<String, String, String> mapper) {
1945         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1946         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1947         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
1948         requireNonNull(mapper, ERROR_MAPPER_NULL);
1949         return createStringBinding(() -> {
1950             String value1 = observable1.getValue();
1951             String value2 = observable2.getValue();
1952             if (value1 != null && value2 != null) {
1953                 return mapper.apply(value1, value2);
1954             }
1955             return supplier.get();
1956         }, observable1, observable2);
1957     }
1958 
1959     /**
1960      * Returns a string binding whose value is the combination of two observable values.
1961      *
1962      @param observable1  the first observable value.
1963      @param observable2  the second observable value.
1964      @param defaultValue the value to be returned if there is no value present, may be null.
1965      @param mapper       a non-interfering, stateless function to apply to the supplied values.
1966      *
1967      @return a string binding
1968      */
1969     @Nonnull
1970     public static StringBinding mapStrings(@Nonnull final ObservableValue<String> observable1, @Nonnull final ObservableValue<String> observable2, @Nullable final String defaultValue, @Nonnull final ObservableValue<BiFunction<String, String, String>> mapper) {
1971         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1972         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1973         requireNonNull(mapper, ERROR_MAPPER_NULL);
1974         return createStringBinding(() -> {
1975             String value1 = observable1.getValue();
1976             String value2 = observable2.getValue();
1977             if (value1 != null && value2 != null) {
1978                 BiFunction<String, String, String> function = mapper.getValue();
1979                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
1980             }
1981             return defaultValue;
1982         }, observable1, observable2, mapper);
1983     }
1984 
1985     /**
1986      * Returns a string binding whose value is the combination of two observable values.
1987      *
1988      @param observable1 the first observable value.
1989      @param observable2 the second observable value.
1990      @param supplier    a {@code Supplier} whose result is returned if no values are present.
1991      @param mapper      a non-interfering, stateless function to apply to the supplied values.
1992      *
1993      @return a string binding
1994      */
1995     @Nonnull
1996     public static StringBinding mapStrings(@Nonnull final ObservableValue<String> observable1, @Nonnull final ObservableValue<String> observable2, @Nonnull final Supplier<String> supplier, @Nonnull final ObservableValue<BiFunction<String, String, String>> mapper) {
1997         requireNonNull(observable1, ERROR_OBSERVABLE1_NULL);
1998         requireNonNull(observable2, ERROR_OBSERVABLE2_NULL);
1999         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
2000         requireNonNull(mapper, ERROR_MAPPER_NULL);
2001         return createStringBinding(() -> {
2002             String value1 = observable1.getValue();
2003             String value2 = observable2.getValue();
2004             if (value1 != null && value2 != null) {
2005                 BiFunction<String, String, String> function = mapper.getValue();
2006                 return requireNonNull(function, ERROR_MAPPER_NULL).apply(value1, value2);
2007             }
2008             return supplier.get();
2009         }, observable1, observable2, mapper);
2010     }
2011 
2012     /**
2013      * Creates an integer binding containing the value of the mapper function applied to the source observable.
2014      *
2015      @param observable the source observable.
2016      *
2017      @return an integer binding.
2018      */
2019     @Nonnull
2020     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<? extends Number> observable) {
2021         return mapInteger(observable, 0);
2022     }
2023 
2024     /**
2025      * Creates an integer binding containing the value of the mapper function applied to the source observable.
2026      *
2027      @param observable   the source observable.
2028      @param defaultValue the value to be returned if there is no value present, may be null.
2029      *
2030      @return an integer binding.
2031      */
2032     @Nonnull
2033     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Integer defaultValue) {
2034         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2035         if (observable instanceof IntegerBinding) {
2036             return (IntegerBindingobservable;
2037         }
2038         return createIntegerBinding(() -> {
2039             Number value = observable.getValue();
2040             return value != null ? value.intValue() : defaultValue;
2041         }, observable);
2042     }
2043 
2044     /**
2045      * Creates an integer binding containing the value of the mapper function applied to the source observable.
2046      *
2047      @param observable the source observable.
2048      @param supplier   a {@code Supplier} whose result is returned if no value is present.
2049      *
2050      @return an integer binding.
2051      */
2052     @Nonnull
2053     public static IntegerBinding mapInteger(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Supplier<Integer> supplier) {
2054         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2055         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
2056         if (observable instanceof IntegerBinding) {
2057             return (IntegerBindingobservable;
2058         }
2059         return createIntegerBinding(() -> {
2060             Number value = observable.getValue();
2061             return value != null ? value.intValue() : supplier.get();
2062         }, observable);
2063     }
2064 
2065     /**
2066      * Creates a long binding containing the value of the mapper function applied to the source observable.
2067      *
2068      @param observable the source observable.
2069      *
2070      @return a long binding.
2071      */
2072     @Nonnull
2073     public static LongBinding mapLong(@Nonnull final ObservableValue<? extends Number> observable) {
2074         return mapLong(observable, 0L);
2075     }
2076 
2077     /**
2078      * Creates a long binding containing the value of the mapper function applied to the source observable.
2079      *
2080      @param observable   the source observable.
2081      @param defaultValue the value to be returned if there is no value present, may be null.
2082      *
2083      @return a long binding.
2084      */
2085     @Nonnull
2086     public static LongBinding mapLong(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Long defaultValue) {
2087         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2088         if (observable instanceof LongBinding) {
2089             return (LongBindingobservable;
2090         }
2091         return createLongBinding(() -> {
2092             Number value = observable.getValue();
2093             return value != null ? value.longValue() : defaultValue;
2094         }, observable);
2095     }
2096 
2097     /**
2098      * Creates a long binding containing the value of the mapper function applied to the source observable.
2099      *
2100      @param observable the source observable.
2101      @param supplier   a {@code Supplier} whose result is returned if no value is present.
2102      *
2103      @return a long binding.
2104      */
2105     @Nonnull
2106     public static LongBinding mapLong(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Supplier<Long> supplier) {
2107         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2108         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
2109         if (observable instanceof LongBinding) {
2110             return (LongBindingobservable;
2111         }
2112         return createLongBinding(() -> {
2113             Number value = observable.getValue();
2114             return value != null ? value.longValue() : supplier.get();
2115         }, observable);
2116     }
2117 
2118     /**
2119      * Creates a float binding containing the value of the mapper function applied to the source observable.
2120      *
2121      @param observable the source observable.
2122      *
2123      @return a float binding.
2124      */
2125     @Nonnull
2126     public static FloatBinding mapFloat(@Nonnull final ObservableValue<? extends Number> observable) {
2127         return mapFloat(observable, 0f);
2128     }
2129 
2130     /**
2131      * Creates a float binding containing the value of the mapper function applied to the source observable.
2132      *
2133      @param observable   the source observable.
2134      @param defaultValue the value to be returned if there is no value present, may be null.
2135      *
2136      @return a float binding.
2137      */
2138     @Nonnull
2139     public static FloatBinding mapFloat(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Float defaultValue) {
2140         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2141         if (observable instanceof FloatBinding) {
2142             return (FloatBindingobservable;
2143         }
2144         return createFloatBinding(() -> {
2145             Number value = observable.getValue();
2146             return value != null ? value.floatValue() : defaultValue;
2147         }, observable);
2148     }
2149 
2150     /**
2151      * Creates a float binding containing the value of the mapper function applied to the source observable.
2152      *
2153      @param observable the source observable.
2154      @param supplier   a {@code Supplier} whose result is returned if no value is present.
2155      *
2156      @return a float binding.
2157      */
2158     @Nonnull
2159     public static FloatBinding mapFloat(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Supplier<Float> supplier) {
2160         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2161         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
2162         if (observable instanceof FloatBinding) {
2163             return (FloatBindingobservable;
2164         }
2165         return createFloatBinding(() -> {
2166             Number value = observable.getValue();
2167             return value != null ? value.floatValue() : supplier.get();
2168         }, observable);
2169     }
2170 
2171     /**
2172      * Creates a double binding containing the value of the mapper function applied to the source observable.
2173      *
2174      @param observable the source observable.
2175      *
2176      @return a double binding.
2177      */
2178     @Nonnull
2179     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<? extends Number> observable) {
2180         return mapDouble(observable, 0d);
2181     }
2182 
2183     /**
2184      * Creates a double binding containing the value of the mapper function applied to the source observable.
2185      *
2186      @param observable   the source observable.
2187      @param defaultValue the value to be returned if there is no value present, may be null.
2188      *
2189      @return a double binding.
2190      */
2191     @Nonnull
2192     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Double defaultValue) {
2193         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2194         if (observable instanceof DoubleBinding) {
2195             return (DoubleBindingobservable;
2196         }
2197         return createDoubleBinding(() -> {
2198             Number value = observable.getValue();
2199             return value != null ? value.doubleValue() : defaultValue;
2200         }, observable);
2201     }
2202 
2203     /**
2204      * Creates a double binding containing the value of the mapper function applied to the source observable.
2205      *
2206      @param observable the source observable.
2207      @param supplier   a {@code Supplier} whose result is returned if no value is present.
2208      *
2209      @return a double binding.
2210      */
2211     @Nonnull
2212     public static DoubleBinding mapDouble(@Nonnull final ObservableValue<? extends Number> observable, @Nullable final Supplier<Double> supplier) {
2213         requireNonNull(observable, ERROR_OBSERVABLE_NULL);
2214         requireNonNull(supplier, ERROR_SUPPLIER_NULL);
2215         if (observable instanceof DoubleBinding) {
2216             return (DoubleBindingobservable;
2217         }
2218         return createDoubleBinding(() -> {
2219             Number value = observable.getValue();
2220             return value != null ? value.doubleValue() : supplier.get();
2221         }, observable);
2222     }
2223 }