Interface Option<Value>

Type Parameters:
Value - The type of the optional value.
All Known Implementing Classes:
Option.None, Option.Some

@NullMarked public sealed interface Option<Value> permits Option.Some<Value>, Option.None<Value>
A sealed interface representing an optional value with two possible states: either a value is present ("Some") or absent ("None").

Unlike Optional, which is a final class, Option is a sealed interface with two record variants — Option.Some and Option.None — enabling exhaustive pattern matching: the compiler enforces that both states are handled in a switch expression without a wildcard arm.

Option<T> participates in the library's type graph with first-class conversion methods: toResult(Object), toTry(Supplier), toEither(Object). The reverse conversions are symmetric: fromOptional(Optional), fromResult(Result), fromTry(Try). The design rationale is documented in ADR-015 — Option<T> as a custom type instead of java.util.Optional.

This interface is NullMarked: all types are non-null by default.

  • Method Details

    • some

      static <V> Option<V> some(V value)
      Creates a Option.Some instance that encapsulates the given non-null value. Use ofNullable(Object) if the value may be null.
      Type Parameters:
      V - the type of the value to encapsulate
      Parameters:
      value - the non-null value to encapsulate
      Returns:
      a Some<V> wrapping the provided value
      Throws:
      NullPointerException - if value is null (enforced by Some(Object))
    • none

      static <V> Option<V> none()
      Creates an instance of Option that represents the absence of a value.
      Type Parameters:
      V - the type of the value that would be held by the Option, if present
      Returns:
      an Option instance that signifies no value is present
    • ofNullable

      static <V> Option<V> ofNullable(@Nullable V value)
      Creates an Option instance that encapsulates a given value. If the value is null, it returns a None instance.
      Type Parameters:
      V - the type of the value to encapsulate
      Parameters:
      value - the value to be encapsulated; if null, a None instance is returned
      Returns:
      an Option containing the provided value if it is non-null, or a None instance if the value is null
    • fromOptional

      static <V> Option<V> fromOptional(Optional<V> optional)
      Converts a given Optional instance into an Option instance.
      Type Parameters:
      V - the type of the value that may be present in the Optional
      Parameters:
      optional - the Optional to be converted; if the Optional contains a value, a Some instance is returned, otherwise a None instance is returned
      Returns:
      an Option containing the value from the Optional if it is present, or an empty None instance if the Optional is empty
    • isDefined

      default boolean isDefined()
      Determines whether this instance represents a defined value.
      Returns:
      true if this instance is of type Some<?> and holds a value; false if it is of type None and does not hold a value.
    • isEmpty

      default boolean isEmpty()
      Checks if this Option instance represents the absence of a value.
      Returns:
      true if this instance is of type None<?>, indicating no value is present; false if this instance holds a value.
    • get

      default Value get()
      Retrieves the value held by this Option instance if it is of type Some. If the instance is of type None, a NoSuchElementException is thrown.
      Returns:
      the encapsulated value if this is an instance of Some
      Throws:
      NoSuchElementException - if this is an instance of None, indicating no value is present
    • getOrElse

      default Value getOrElse(Value fallback)
      Retrieves the encapsulated value if this Option instance is of type Some, or returns the provided fallback value if this instance is of type None.
      Parameters:
      fallback - the value to return if this instance is None
      Returns:
      the encapsulated value if this instance is a Some, or the specified fallback value if this instance is None
    • getOrElseGet

      default Value getOrElseGet(Supplier<? extends Value> fallbackSupplier)
      Retrieves the encapsulated value if this Option instance is of type Some, or computes and returns a fallback value supplied by the given fallbackSupplier if this instance is of type None.
      Parameters:
      fallbackSupplier - a Supplier that provides a fallback value if this instance represents the absence of a value
      Returns:
      the encapsulated value if this instance is a Some, or the fallback value computed by the fallbackSupplier if this instance is a None
    • orElse

      default Option<Value> orElse(Option<? extends Value> alternative)
      Returns this Option if it is Some, otherwise returns alternative.
      Parameters:
      alternative - the fallback Option to return when this is None; must not be null
      Returns:
      this instance if Some, otherwise alternative
      Throws:
      NullPointerException - if alternative is null
    • orElse

      default Option<Value> orElse(Supplier<? extends Option<? extends Value>> alternative)
      Returns this Option if it is Some, otherwise evaluates and returns the supplier's result. The supplier is not called when this is Some.
      Parameters:
      alternative - a lazy supplier of a fallback Option; must not return null
      Returns:
      this instance if Some, or the result of alternative.get() if None
      Throws:
      NullPointerException - if alternative is null or returns null
    • getOrNull

      default Value getOrNull()
      Retrieves the encapsulated value if this Option instance is of type Some, or returns null if this instance is of type None.
      Returns:
      the encapsulated value if this instance is a Some, or null if this instance is a None.
    • getOrThrow

      default Value getOrThrow(Supplier<? extends RuntimeException> exceptionSupplier)
      Retrieves the encapsulated value if this Option instance is of type Some. If the instance is of type None, it throws an exception provided by the given exceptionSupplier.
      Parameters:
      exceptionSupplier - a Supplier that provides the exception to be thrown if this instance is of type None
      Returns:
      the encapsulated value if this instance is of type Some
      Throws:
      RuntimeException - if this instance is of type None, using the exception provided by exceptionSupplier
    • map

      default <NewValue> Option<NewValue> map(Function<? super Value, ? extends NewValue> mapper)
      Transforms the current Option using the provided mapping function. If the current Option is a Some, applies the provided mapper to its value. If the current Option is a None, returns None without applying the mapper.
      Type Parameters:
      NewValue - the type of the value in the resulting Option after transformation
      Parameters:
      mapper - the function to apply to the value if this Option is a Some; must not be null and must not return null
      Returns:
      a new Option containing the mapped value if this is a Some, or None if this is a None
      Throws:
      NullPointerException - if mapper is null or returns null
    • flatMap

      default <NewValue> Option<NewValue> flatMap(Function<? super Value, Option<NewValue>> mapper)
      Transforms the current Option value using the provided mapping function and flattens the result. If the Option is empty (None), it remains empty. Otherwise, it applies the mapping function to the encapsulated value and returns the resulting Option.
      Type Parameters:
      NewValue - the type of the element contained in the resulting Option
      Parameters:
      mapper - the function to apply to the encapsulated value, which produces a new Option
      Returns:
      a new Option resulting from applying the mapping function and flattening
      Throws:
      NullPointerException - if the mapping function returns null
    • filter

      default Option<Value> filter(Predicate<? super Value> predicate)
      Filters the value of this Option based on the provided predicate. If this Option is a Some and the predicate evaluates to true, the Option is returned as-is. If the predicate evaluates to false, or this Option is a None, an empty Option is returned.
      Parameters:
      predicate - the predicate used to test the value inside this Option
      Returns:
      an Option containing the value if the predicate evaluates to true, otherwise an empty Option
    • peek

      default Option<Value> peek(Consumer<? super Value> action)
      Applies the provided action to the value contained in this instance if it is of type Some.
      Parameters:
      action - a Consumer that performs an operation on the contained value
      Returns:
      this instance after applying the provided action
    • fold

      default <Folded> Folded fold(Supplier<? extends Folded> onNone, Function<? super Value, ? extends Folded> onSome)
      Folds the current option into a single value by applying the appropriate function depending on whether the option is a Some or a None.
      Type Parameters:
      Folded - The type of the resulting value after folding.
      Parameters:
      onNone - A supplier to provide a value in case the option is None.
      onSome - A function to transform the value in case the option is Some.
      Returns:
      The folded value of type Folded resulting from applying the appropriate supplier or function.
    • match

      default void match(Runnable onNone, Consumer<? super Value> onSome)
      Executes one of the provided actions based on the state of this value. If the value is "Some", the provided consumer is executed with the inner value. If the value is "None", the provided runnable is executed.
      Parameters:
      onNone - the action to execute if the value is "None"
      onSome - the consumer to execute if the value is "Some", accepting the inner value
    • stream

      default Stream<Value> stream()
      Returns a stream representation of the current instance. If the instance is of type Some<Value>, the stream contains the value. If the instance is of type None<Value>, the stream is empty.

      Java 9+ Optional has stream(); this mirrors that. - Some(v) -> Stream.of(v) - None -> Stream.empty()

      Returns:
      a stream containing the value if present, or an empty stream if no value exists
    • toOptional

      default Optional<Value> toOptional()
      Converts the current instance of a value or none container into an Optional.
      Returns:
      an Optional containing the value if the instance is of type Some, or an empty Optional if the instance is of type None.
    • toFuture

      default CompletableFuture<Value> toFuture()
      Converts this Option into an already-completed CompletableFuture.

      Example:

      Option.some("hello").toFuture(); // CompletableFuture completed with "hello"
      Option.none().toFuture();        // CompletableFuture failed with NoSuchElementException
      
      Returns:
      a completed or failed CompletableFuture<Value>
    • collectPresent

      static <V> List<V> collectPresent(Stream<Option<V>> options)
      Collects all present (non-empty) values from a stream of Option instances into an unmodifiable list.
      Type Parameters:
      V - the type of the values inside the Option instances
      Parameters:
      options - a stream of Option instances
      Returns:
      an unmodifiable list containing all present values from the provided stream
    • presentValuesToList

      static <V> Collector<Option<? extends V>, ?, List<V>> presentValuesToList()
      Creates a collector that transforms a stream of Option objects into a list of values by extracting the present values and filtering out any absent values.
      Type Parameters:
      V - the type of the values inside the Option objects
      Returns:
      a Collector that collects present values into a List
    • sequenceCollector

      static <V> Collector<Option<V>, ?, Option<List<V>>> sequenceCollector()
      Returns a Collector that reduces a Stream<Option<V>> to a single Optional<List<V>>.

      The result is Some only if every element in the stream is Some. The first None causes the entire result to be none(). An empty stream yields an empty list wrapped in Option.some.

      This mirrors sequence(Iterable) but operates as a stream Collector.

      Example:

      Option<List<User>> allFound = ids.stream()
          .map(userRepo::findById)             // Stream<Option<User>>
          .collect(Option.sequenceCollector()); // Option<List<User>>
      
      Type Parameters:
      V - the element type inside each Option
      Returns:
      a collector producing Option<List<V>>
    • sequence

      static <V> Option<List<V>> sequence(Iterable<Option<V>> options)
      Transforms an iterable of Option<V> into a single Option<List<V>>. If any element in the input iterable is None, this method returns Option.none(). If all elements are Some, the result is Option.some() containing a list of values.
      Type Parameters:
      V - The type of the values wrapped in the Option.
      Parameters:
      options - An iterable containing Option<V> elements to be transformed.
      Returns:
      Option.some() containing a list of values if all elements are Some, or Option.none() if any element is None.
      Throws:
      NullPointerException - If the options iterable is null or contains null elements.
    • sequence

      static <V> Option<List<V>> sequence(Stream<Option<V>> options)
      Converts a stream of Option objects into a single Option containing a List of values, if all Option instances in the stream are Option.Some. If the stream contains any Option.None, the result will be none().
      Type Parameters:
      V - the type of elements contained in the Option instances
      Parameters:
      options - a stream of Option elements to be sequenced
      Returns:
      an Option containing a List of values if all elements are Option.Some, or none() if any element in the stream is Option.None
      Throws:
      NullPointerException - if the stream or any of its elements is null
    • traverse

      static <A,B> Option<List<B>> traverse(Iterable<A> values, Function<? super A, Option<B>> mapper)
      Transforms a collection of values of type A into an optional list of values of type B by applying a given mapping function to each element in the input collection. If the mapping function returns a None for any element, this method returns Option.none().
      Type Parameters:
      A - the type of the elements in the input collection
      B - the type of the elements in the resulting optional list
      Parameters:
      values - the collection of input values to be transformed, must not be null
      mapper - the mapping function to apply to each element in the input collection, must not return null or Option.none() for valid outputs
      Returns:
      an Option containing a list of transformed values if all transformations succeed, or Option.none() if the mapping function produces a None for any element
      Throws:
      NullPointerException - if values or mapper is null, or if the mapping function returns null
    • traverse

      static <A,B> Option<List<B>> traverse(Stream<A> values, Function<? super A, Option<B>> mapper)
      Transforms a stream of values by applying a mapper function that returns an Option for each input value. If the mapper function returns None for any value, the entire result is None. Otherwise, returns a Some wrapping a list of mapped values.
      Type Parameters:
      A - the type of the input elements in the stream
      B - the type of the elements in the output List
      Parameters:
      values - the stream of input values to traverse
      mapper - the mapping function to transform each input value into an Option of the output type
      Returns:
      an Option containing a List of transformed values if all inputs are successfully mapped, or None if the mapper returns None for any value
      Throws:
      NullPointerException - if values or mapper is null, or if the mapper function returns null for any input
    • toResult

      default <TError> Result<Value,TError> toResult(TError errorIfNone)
      Converts the current option to a Result instance.
      Type Parameters:
      TError - the type of the error value.
      Parameters:
      errorIfNone - the error value to use if the current option is None; must not be null
      Returns:
      a Result containing the value if this is Some, or an error if this is None.
      Throws:
      NullPointerException - if errorIfNone is null
    • toTry

      default Try<Value> toTry(Supplier<? extends Throwable> exceptionSupplier)
      Converts the current instance to a Try instance.
      Parameters:
      exceptionSupplier - a supplier that provides the exception to be used when the current instance is None.
      Returns:
      a Try instance containing the value if the current instance is Some, or a failed Try with the supplied exception if the current instance is None.
    • toEither

      default <L> Either<L,Value> toEither(L leftIfNone)
      Converts this Option to an Either.

      Some(v) maps to Either.right(Object); None maps to Either.left(Object) using the supplied left value. Mirrors the existing toResult(Object) overload for the neutral two-track type.

      Type Parameters:
      L - the left type
      Parameters:
      leftIfNone - the value to use as the Either.Left when this is None; must not be null
      Returns:
      an Either<L, Value> equivalent of this Option
      Throws:
      NullPointerException - if leftIfNone is null
    • fromResult

      static <V,E> Option<V> fromResult(Result<? extends V, ? extends E> result)
      Converts a Result into an Option.

      If the given result represents a successful value (i.e., isOk() returns true), the value is wrapped in an Option. Otherwise, Option.none() is returned.

      Type Parameters:
      V - the type of the value contained in the result
      E - the type of the error contained in the result
      Parameters:
      result - the Result to be converted, must not be null
      Returns:
      an Option containing the value from the result if it is successful, or an Option.none() if the result contains an error
    • fromTry

      static <V> Option<V> fromTry(Try<? extends V> t)
      Converts a Try instance into an Option. If the Try is successful, the resulting Option contains the value. If the Try is a failure, the resulting Option is empty.
      Type Parameters:
      V - the type of the value contained in the Try
      Parameters:
      t - the Try instance to convert, must not be null
      Returns:
      an Option containing the value if the Try is successful, or an empty Option if it is a failure
    • fromTryOptional

      static <V> Option<V> fromTryOptional(Try<Optional<V>> t)
      Converts a Try<Optional<V>> into an Option<V>, flattening both layers in a single step.
      • Success(Optional.of(v))Some(v)
      • Success(Optional.empty())None
      • Failure(ex)None
      Type Parameters:
      V - the type of the value inside the Optional
      Parameters:
      t - the Try wrapping an Optional value, must not be null
      Returns:
      an Option containing the value if present and the Try succeeded, or none() otherwise
    • fromEither

      static <L,R> Option<R> fromEither(Either<? extends L, ? extends R> either)
      Converts an Either into an Option, keeping only the Either.Right value.

      This is the static complement of Either.toOption(): both express the same conversion but from different call sites.

      Type Parameters:
      L - the left type (discarded on conversion)
      R - the right type (preserved as the Option value)
      Parameters:
      either - the Either to convert; must not be null
      Returns:
      Some(r) if either is Right, otherwise None
      Throws:
      NullPointerException - if either is null
    • zip

      default <B> Option<Tuple2<Value,B>> zip(Option<? extends B> other)
      Combines the current Option instance with another Option instance into a single Option containing a Tuple2 of their values, if both options are non-empty.
      Type Parameters:
      B - the type of the value contained in the other Option
      Parameters:
      other - the other Option to combine with
      Returns:
      an Option containing a Tuple2 of the values from both options if both are non-empty, otherwise an empty Option
    • zipWith

      default <B,R> Option<R> zipWith(Option<? extends B> other, BiFunction<? super Value, ? super B, ? extends R> combiner)
      Combines the values of this Option with the values of another Option using a provided combining function.
      Type Parameters:
      B - the type of the value contained in the other Option
      R - the type of the result produced by the combining function
      Parameters:
      other - the other Option to combine with
      combiner - the function to combine the values from this Option and the other Option
      Returns:
      an Option containing the result of applying the combining function to the values, or an empty Option if either this Option or the other Option is empty
    • zipWith

      default <B> Option<Tuple2<Value,B>> zipWith(Function<? super Value, ? extends Option<? extends B>> mapper)
      Applies mapper to the value inside this Option and pairs the original value with the result. Returns none() if this is empty or if the mapper returns none().

      This is the monadic "dependent zip": the second Option is computed from the first value, unlike zip(Option) which takes an already-evaluated option.

      Option<String> name = Option.some("alice");
      Option<Tuple2<String, Integer>> result =
          name.zipWith(n -> lookupAge(n));
      // Some(Tuple2("alice", 30)) if lookupAge returns Some(30)
      // None                      if lookupAge returns None
      
      Type Parameters:
      B - type of the value produced by mapper
      Parameters:
      mapper - function that receives this option's value and returns an Option<B>; must not be null, and must not return null
      Returns:
      Some(Tuple2(thisValue, b)) if both are present, otherwise None
      Throws:
      NullPointerException - if mapper is null or if mapper returns null
    • flatZip

      default <B> Option<Tuple2<Value,B>> flatZip(Function<? super Value, ? extends Option<? extends B>> mapper)
      Alias for zipWith(Function).

      Applies mapper to the value inside this Option and pairs the original value with the result. Useful when the name flatZip better communicates intent at the call site.

      Type Parameters:
      B - type of the value produced by mapper
      Parameters:
      mapper - function that receives this option's value and returns an Option<B>; must not be null, and must not return null
      Returns:
      Some(Tuple2(thisValue, b)) if both are present, otherwise None
      Throws:
      NullPointerException - if mapper is null or if mapper returns null
    • zip3

      default <B,C> Option<Tuple3<Value,B,C>> zip3(Option<? extends B> b, Option<? extends C> c)
      Combines this Option with two others into an Option<Tuple3>. Returns none() if any of the three is empty.
      Type Parameters:
      B - type of the value in b
      C - type of the value in c
      Parameters:
      b - second option; must not be null
      c - third option; must not be null
      Returns:
      Some(Tuple3(v1, v2, v3)) if all three are non-empty, otherwise None
      Throws:
      NullPointerException - if b or c is null
    • zipWith3

      default <B,C,R> Option<R> zipWith3(Option<? extends B> b, Option<? extends C> c, TriFunction<? super Value, ? super B, ? super C, ? extends R> combiner)
      Combines this Option with two others using a TriFunction. Returns none() if any of the three is empty.
      Type Parameters:
      B - type of the value in b
      C - type of the value in c
      R - result type
      Parameters:
      b - second option; must not be null
      c - third option; must not be null
      combiner - function applied to the three values; must not be null
      Returns:
      Some(combiner(v1, v2, v3)) if all three are non-empty, otherwise None
      Throws:
      NullPointerException - if b, c, or combiner is null
    • zip4

      default <B,C,D> Option<Tuple4<Value,B,C,D>> zip4(Option<? extends B> b, Option<? extends C> c, Option<? extends D> d)
      Combines this Option with three others into an Option<Tuple4>. Returns none() if any of the four is empty.
      Type Parameters:
      B - type of the value in b
      C - type of the value in c
      D - type of the value in d
      Parameters:
      b - second option; must not be null
      c - third option; must not be null
      d - fourth option; must not be null
      Returns:
      Some(Tuple4(v1, v2, v3, v4)) if all four are non-empty, otherwise None
      Throws:
      NullPointerException - if b, c, or d is null
    • zipWith4

      default <B,C,D,R> Option<R> zipWith4(Option<? extends B> b, Option<? extends C> c, Option<? extends D> d, QuadFunction<? super Value, ? super B, ? super C, ? super D, ? extends R> combiner)
      Combines this Option with three others using a QuadFunction. Returns none() if any of the four is empty.
      Type Parameters:
      B - type of the value in b
      C - type of the value in c
      D - type of the value in d
      R - result type
      Parameters:
      b - second option; must not be null
      c - third option; must not be null
      d - fourth option; must not be null
      combiner - function applied to the four values; must not be null
      Returns:
      Some(combiner(v1, v2, v3, v4)) if all four are non-empty, otherwise None
      Throws:
      NullPointerException - if b, c, d, or combiner is null
    • zip

      static <A,B> Option<Tuple2<A,B>> zip(Option<? extends A> a, Option<? extends B> b)
      Combines two Option instances into a single Option containing a Tuple2 of the values if both options are non-empty. If either option is empty, returns an empty Option.

      zip: Option<A> + Option<B> -> Option<Tuple2<A,B>>

      Type Parameters:
      A - the type of the value in the first Option
      B - the type of the value in the second Option
      Parameters:
      a - the first Option instance, must not be null
      b - the second Option instance, must not be null
      Returns:
      an Option containing a Tuple2 of the values if both options are non-empty, otherwise an empty Option
      Throws:
      NullPointerException - if either a or b is null
    • map2

      static <A,B,R> Option<R> map2(Option<? extends A> a, Option<? extends B> b, BiFunction<? super A, ? super B, ? extends R> combiner)
      Combines the values of two Option instances using the provided combiner function. If either Option is empty (None), the result is an empty Option. If both Options contain values, the combiner function is applied and the result is wrapped in an Option.
      Type Parameters:
      A - the type of the value contained in the first Option
      B - the type of the value contained in the second Option
      R - the type of the value contained in the resulting Option
      Parameters:
      a - the first Option, which may or may not contain a value
      b - the second Option, which may or may not contain a value
      combiner - the function used to combine the values of a and b if both are present
      Returns:
      an Option containing the result of applying the combiner function to the values of a and b, or an empty Option if either a or b is empty
    • zip3

      static <A,B,C> Option<Tuple3<A,B,C>> zip3(Option<? extends A> a, Option<? extends B> b, Option<? extends C> c)
      Combines three Option instances into a single Option containing a Tuple3. Returns none() if any of the three is empty.
      Type Parameters:
      A - type of the value in a
      B - type of the value in b
      C - type of the value in c
      Parameters:
      a - first option; must not be null
      b - second option; must not be null
      c - third option; must not be null
      Returns:
      Some(Tuple3(av, bv, cv)) when all three are non-empty, otherwise None
      Throws:
      NullPointerException - if a, b, or c is null
    • map3

      static <A,B,C,R> Option<R> map3(Option<? extends A> a, Option<? extends B> b, Option<? extends C> c, TriFunction<? super A, ? super B, ? super C, ? extends R> combiner)
      Combines the values of three Option instances using the provided TriFunction. Returns none() if any of the three is empty.
      Type Parameters:
      A - type of the value in a
      B - type of the value in b
      C - type of the value in c
      R - result type
      Parameters:
      a - first option; must not be null
      b - second option; must not be null
      c - third option; must not be null
      combiner - function applied to the three values; must not be null
      Returns:
      Some(combiner(av, bv, cv)) when all three are non-empty, otherwise None
      Throws:
      NullPointerException - if any argument is null
    • zip4

      static <A,B,C,D> Option<Tuple4<A,B,C,D>> zip4(Option<? extends A> a, Option<? extends B> b, Option<? extends C> c, Option<? extends D> d)
      Combines four Option instances into a single Option containing a Tuple4. Returns none() if any of the four is empty.
      Type Parameters:
      A - type of the value in a
      B - type of the value in b
      C - type of the value in c
      D - type of the value in d
      Parameters:
      a - first option; must not be null
      b - second option; must not be null
      c - third option; must not be null
      d - fourth option; must not be null
      Returns:
      Some(Tuple4(av, bv, cv, dv)) when all four are non-empty, otherwise None
      Throws:
      NullPointerException - if a, b, c, or d is null
    • map4

      static <A,B,C,D,R> Option<R> map4(Option<? extends A> a, Option<? extends B> b, Option<? extends C> c, Option<? extends D> d, QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> combiner)
      Combines the values of four Option instances using the provided QuadFunction. Returns none() if any of the four is empty.
      Type Parameters:
      A - type of the value in a
      B - type of the value in b
      C - type of the value in c
      D - type of the value in d
      R - result type
      Parameters:
      a - first option; must not be null
      b - second option; must not be null
      c - third option; must not be null
      d - fourth option; must not be null
      combiner - function applied to the four values; must not be null
      Returns:
      Some(combiner(av, bv, cv, dv)) when all four are non-empty, otherwise None
      Throws:
      NullPointerException - if any argument is null