public static <T1, T2, R> R requireNonNull(final T1 value,
                                               final Function<T1, T2> getter1,
                                               final Function<T2, R> getter2,
                                               final Supplier<String> messageSupplier) {
        if (value == null) {
            throw new NullPointerException(buildNullValueMsg("value", messageSupplier));
        } else {
            final T2 value2 = Objects.requireNonNull(getter1, "Null getter1")
                    .apply(value);
            if (value2 == null) {
                throw new NullPointerException(buildNullGetterResultMsg(1, messageSupplier));
            } else {
                final R result = Objects.requireNonNull(getter2, "Null getter2")
                        .apply(value2);
                if (result == null) {
                    throw new NullPointerException(buildNullGetterResultMsg(2, messageSupplier));
                } else {
                    return result;
                }
            }
        }
    }
Require that {@code value} is non-null, the result of applying {@code getter1} to
{@code value} is non-null and the result applying {@code getter2} to the result
of {@code getter1} is non-null. Throws an {@link NullPointerException} otherwise.

@throws NullPointerException
stroom-util-shared/src/main/java/stroom/util/shared/NullSafe.java