@startuml

'left to right direction
top to bottom direction

interface ShellCommand
ShellCommand : +String getName()
ShellCommand : +String execute(String params) throws CommandFault
ShellCommand : +String getHelpString()

class PrintCommand
class TimeCommand
class HelpCommand
class ExitCommand

ShellCommand <|-- PrintCommand
ShellCommand <|-- TimeCommand
ShellCommand <|-- HelpCommand
ShellCommand <|-- ExitCommand

abstract CommandFault
CommandFault : +Severity getSeverity()
CommandFault : +String getMessage()

CommandFault - Severity : has >

class InfoFault
class ErrorFault
class FatalFault

CommandFault <|-- InfoFault
CommandFault <|-- ErrorFault
CommandFault <|-- FatalFault

ShellCommand - CommandFault : throws >

interface CommandRegistry
CommandRegistry : +Optional<ShellCommand> getCommand(String commandName)
CommandRegistry : +Map<String, ShellCommand> getAllCommands()
ShellCommand "many" o-- "1" CommandRegistry : contains

class SpringBasedCommandRegistry
SpringBasedCommandRegistry <|-- CommandRegistry

enum Severity{
  INFO
  ERROR
  FATAL
}

interface FaultHandler
FaultHandler : +boolean accept(CommandFault fault)
FaultHandler : +void handleFault(CommandFault fault)

class InfoFaultHandler
class ErrorFaultHandler
class FatalFaultHandler

FaultHandler <|-- InfoFaultHandler
FaultHandler <|-- ErrorFaultHandler
FaultHandler <|-- FatalFaultHandler

class CommandFaultHandler
CommandFaultHandler : +void handleFault(CommandFault fault) 

FaultHandler "many" o-- "1" CommandFaultHandler : contains
FaultHandler - CommandFault : handles >

CommandRegistry o-- HelpCommand

interface OutputPrinter
OutputPrinter : +print(PrintParams params)
OutputPrinter - PrintParams : prints >
class ConsolePrinter
class FilePrinter

OutputPrinter <|-- ConsolePrinter
OutputPrinter <|-- FilePrinter

class PrintParams
PrintParams : -String command
PrintParams : -String message

class Shell
Shell : +executeCommand(String command) 

CommandFaultHandler o-- Shell : uses
CommandRegistry o-- Shell : uses
OutputPrinter o-- Shell : uses

@enduml