protected static <T extends AbstractOption<T, U, V>, U extends AbstractOptionValue<U, T, V>, V>
    T define(Class<?> type, String name, V defaultValue,
             Factory<T, U, V> optionFactory, Function<V, V> validator, BiFunction<U, U, U> mergeFunction) {

        requireNonNull(type, "type");
        requireNonNull(name, "name");
        requireNonNull(defaultValue, "defaultValue");
        requireNonNull(optionFactory, "optionFactory");
        requireNonNull(validator, "validator");
        requireNonNull(mergeFunction, "mergeFunction");

        return map.get(type)
                  .define(optionFactory, name, defaultValue, validator, mergeFunction);
    }
Defines a new option.

@param type the type of the option, e.g. {@link ClientOption}.
@param name the name of the option, e.g. {@code "RESPONSE_TIMEOUT_MILLIS"}.
@param defaultValue the default value of the option.
@param optionFactory the {@link Factory} that creates a new option.
@param validator the {@link Function} which is used for validating ane normalizing an option value.
@param mergeFunction the {@link BiFunction} which is used for merging old and new option values.
@param <T> the type of the option.
@param <U> the type of the option value holder.
@param <V> the type of the option value.

@return a new option instance.

@throws IllegalStateException if an option with the specified name exists already.
core/src/main/java/com/linecorp/armeria/common/util/AbstractOption.java