@startuml

    !include lexakai.theme
    
    title "com.telenav.kivakit.core.function"
    
    interface RepeaterMixin
    interface SilentTryTrait
    interface Presence
    
    class Functions
    {
        --(write)--
        +Output apply(Input value, Function<Input,Output>)
    }
    
    Presence <|-- Maybe
    SilentTryTrait <|-- Maybe
    class Maybe<Value>
    {
        --(constructors)--
        #Maybe()
        #Maybe(Maybe<Value>)
        #Maybe(Value)
        --
        +Maybe<Value> absent()
        +Maybe<Value> absentIf(BooleanFunction<Value> predicate)
        +Maybe<Output> apply(Function<? super Value,? extends Maybe<? extends Output>>)
        +Stream<Value> asStream()
        +Value get()
        +boolean has()
        +Maybe<Value> ifPresent(Consumer<Value>)
        +Maybe<Value> ifPresentOr(Consumer<Value>, UncheckedVoidCode runnable)
        +Maybe<Value> maybe(Value)
        +Value orDefaultTo(Value defaultValue)
        +Value orDefaultTo(Source<Value> defaultValue)
        +Maybe<Value> orMaybe(Source<Value>)
        +Maybe<Value> orMaybe(Value)
        +Value orThrow()
        +Value orThrow(String message, Object... arguments)
        +Maybe<Value> present(Value)
        +Maybe<Value> presentIf(BooleanFunction<Value> predicate)
        +Maybe<Value> set(Value)
        +Maybe<Value> then(TetraFunction<Value,Argument2,Argument3,Argument4,Value>, Argument2, Argument3, Argument4)
        +Maybe<Value> then(BiFunction<Value,Argument2,Value>, Argument2)
        +Maybe<Value> then(Function<Value,Value>)
        +Maybe<Value> then(TriFunction<Value,Argument2,Argument3,Value>, Argument2, Argument3)
        +Maybe<Value> then(PentaFunction<Value,Argument2,Argument3,Argument4,Argument5,Value>, Argument2, Argument3, Argument4, Argument5)
        --(checks)--
        +boolean isPresent()
        +boolean isValid()
        --(collection)--
        +Maybe<ResultType> map(TriFunction<Value,Argument2,Argument3,ResultType>, Argument2, Argument3)
        +Maybe<ResultType> map(TetraFunction<Value,Argument2,Argument3,Argument4,ResultType>, Argument2, Argument3, Argument4)
        +Maybe<ResultType> map(BiFunction<Value,Argument2,ResultType>, Argument2)
        +Maybe<ResultType> map(Function<? super Value,? extends ResultType> mapper)
        +Maybe<ResultType> map(PentaFunction<Value,Argument2,Argument3,Argument4,Argument5,ResultType>, Argument2, Argument3, Argument4, Argument5)
        --(factory)--
        #Maybe<T> newAbsent()
        #Maybe<T> newMaybe(T value)
    }
    
    Maybe <|-- Result
    RepeaterMixin <|-- Result
    Result --> Message : "failure reason"
    class Result<Value>
    {
        --(constructors)--
        #Result()
        #Result(Broadcaster)
        #Result(Maybe<Value>)
        #Result(Value)
        --
        +Result<Value> absent()
        +Result<Mapped> apply(Function<? super Value,? extends Maybe<? extends Mapped>>)
        +Result<T> capture(Broadcaster value)
        +Maybe<Output> convert(Class<Mapper> mapperType)
        +boolean failed()
        +Result<Value> ifPresent(Consumer<Value>)
        +Result<Value> ifPresentOr(Consumer<Value>, UncheckedVoidCode runnable)
        +Result<T> present(T value)
        +Result<Value> presentIf(BooleanFunction<Value> predicate)
        +Result<Value> then(Function<Value,Value>)
        --(collection)--
        +Result<Output> map(Function<? super Value,? extends Output> mapper)
        +Result<R> map(BiFunction<Value,Argument2,R>, Argument2)
        +MessageList messages()
        --(lifecycle)--
        +Result<T> run(Broadcaster, Code<T>)
        --(logical)--
        +Result<Value> or(Code<Value>)
        --(messaging)--
        +Value orProblem(String message, Object... arguments)
        --(status)--
        +Result<T> failure(Result<T>, String message, Object... arguments)
        +Result<T> failure(Throwable cause, String message, Object... arguments)
        +Result<T> failure(String message, Object... arguments)
        +Result<T> failure(Message)
        +boolean succeeded()
        +Result<T> success(T value)
        +Result<Value> success(Maybe<Value>)
    }
    
    interface Repeater
    Repeater <|-- ResultTrait
    interface ResultTrait
    {
        --
        +Result<T> absent()
        --(lifecycle)--
        +Result<T> run(Code<T>)
        --(status)--
        +Result<T> failure(Throwable, String message, Object... arguments)
        +Result<T> failure(String message, Object... arguments)
        +Result<T> failure(Message)
        +Result<T> success(T value)
        +Result<T> success(Maybe<T> value)
    }
    
@enduml

