### Question:
ToBooleanNullableImpl implements NullableExpression<T, ToBoolean<T>>, ToBooleanNullable<T> { @Override public boolean equals(Object o) { if (this == o) return true; else if (!(o instanceof NullableExpression)) return false; final NullableExpression<?, ?> that = (NullableExpression<?, ?>) o; return Objects.equals(original, that.inner()) && Objects.equals(isNull, that.isNullPredicate()); } ToBooleanNullableImpl(ToBoolean<T> original, Predicate<T> isNull); @Override ToBoolean<T> inner(); @Override Predicate<T> isNullPredicate(); @Override Boolean apply(T t); @Override boolean applyAsBoolean(T t); @Override ToBoolean<T> orThrow(); @Override ToBoolean<T> orElseGet(ToBoolean<T> getter); @Override ToBoolean<T> orElse(Boolean value); @Override ToDoubleNullable<T> mapToDoubleIfPresent(BooleanToDoubleFunction mapper); @Override ToBooleanNullable<T> mapIfPresent(BooleanUnaryOperator mapper); @Override long hash(T object); @Override int compare(T first, T second); @Override boolean isNull(T object); @Override boolean isNotNull(T object); @Override boolean equals(Object o); @Override int hashCode();  }### Answer:
@Test void testEquals() { final ToBooleanNullable<String> copy = instance; assertTrue(instance.equals(copy)); assertFalse(instance.equals(null)); final ToBooleanNullable<String> another = new ToBooleanNullableImpl<>( instance.inner(), instance.isNullPredicate() ); final ToBooleanNullable<String> originalSame = new ToBooleanNullableImpl<>( instance.inner(), Objects::isNull ); final ToBooleanNullable<String> isNullSame = new ToBooleanNullableImpl<>( string -> string.length() > 2, instance.isNullPredicate() ); assertTrue(instance.equals(another)); assertFalse(instance.equals(originalSame)); assertFalse(instance.equals(isNullSame)); }