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