     case error(String)
     case emptyError
 }
-
-#if os(Linux)
-#if swift(>=3.1)
-typealias Regex = NSRegularExpression
-#else
-typealias Regex = RegularExpression
-#endif
-#else
-typealias Regex = NSRegularExpression
-
-#endif


import Foundation

extension CLI {
    
    static var shared: CLI?
    
    private static func guardShared() -> CLI {
        guard let cli = shared else {
            fatalError("Call CLI.setup() before making other calls")
        }
        return cli
    }
    
    // MARK: - Information
    
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static var name: String {
        get {
            return guardShared().name
        }
    }
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static var version: String? {
        get {
            return guardShared().version
        }
    }
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static var description: String? {
        get {
            return guardShared().description
        }
        set(newValue) {
            guardShared().description = newValue
        }
    }
    @available(*, unavailable, message: "Create a custom HelpMessageGenerator instead")
    public static var helpCommand: Command? = nil
    
    @available(*, unavailable, message: "Create the CLI object with a nil version and register a custom version command")
    public static var versionCommand: Command? = nil
    
    // MARK: - Advanced customization
    
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static var helpMessageGenerator: HelpMessageGenerator {
        get {
            return guardShared().helpMessageGenerator
        }
        set(newValue) {
            guardShared().helpMessageGenerator = newValue
        }
    }
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static var argumentListManipulators: [ArgumentListManipulator] {
        get {
            return guardShared().argumentListManipulators
        }
        set(newValue) {
            guardShared().argumentListManipulators = newValue
        }
    }
    
    // MARK: - Setup
    
    /// Sets the CLI up with basic information
    ///
    /// - Parameters:
    ///   - name: name of the app, printed in the help message and command usage statements
    ///   - version: version of the app, printed by the VersionCommand
    ///   - description: description of the app, printed in the help message
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static func setup(name: String, version: String? = nil, description: String? = nil) {}
    
    /// Registers a command with the CLI for routing and execution. All commands must be registered
    /// with this method or its siblings before calling `CLI.go()`
    ///
    /// - Parameter command: the command to be registered
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static func register(command: Command) {}
    
    /// Registers a group of commands with the CLI for routing and execution. All commands must be registered
    /// with this method or its siblings before calling `CLI.go()`
    ///
    /// - Parameter commands: the commands to be registered
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static func register(commands: [Command]) {}
    
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static func go() -> Int32 {
        return guardShared().go()
    }
    
    @available(*, unavailable, message: "Create a new CLI object: let cli = CLI(..)")
    public static func debugGo(with argumentString: String) -> Int32 {
        return guardShared().debugGo(with: argumentString)
    }
    
    @available(*, unavailable, message: "Use a custom parser instead: cli.parser = Parser(router: MyRouter())")
    public var router: Router {


extension Input {
    
    @available(*, unavailable, message: "Use Input.readLine()")
    public static func awaitInput(message: String?, secure: Bool = false) -> String { return "" }
    
    @available(*, unavailable, message: "Use Input.readLine() with a validation closure")
    public static func awaitInputWithValidation(message: String?, secure: Bool = false, validation: (_ input: String) -> Bool) -> String { return "" }
    
    @available(*, unavailable, message: "Implement CovertibleFromString on a custom object and use Input.readObject()")
    public static func awaitInputWithConversion<T>(message: String?, secure: Bool = false, conversion: (_ input: String) -> T?) -> T { return conversion("")! }
    
    @available(*, unavailable, message: "Use Input.readInt() instead")
    public static func awaitInt(message: String?) -> Int { return 0 }
    
    @available(*, unavailable, message: "Use Input.readBool() instead")
    public static func awaitYesNoInput(message: String = "Confirm?") -> Bool { return false }
    
}

@available(*, unavailable, renamed: "WritableStream")
public typealias OutputByteStream = WritableStream

@available(*, unavailable, message: "Use WriteStream.stdout instead")
public class StdoutStream: WriteStream {}

@available(*, unavailable, message: "Use WriteStream.stderr instead")
public class StderrStream: WriteStream {}

@available(*, unavailable, message: "Use WriteStream.null instead")
public class NullStream: WriteStream {}

@available(*, unavailable, renamed: "WriteStream")
public typealias FileStream = WriteStream

extension WritableStream {
    
    @available(*, unavailable, renamed: "print")
    func output(_ content: String) {}
    
    @available(*, unavailable, renamed: "print")
    public func output(_ content: String, terminator: String) {}
    
}

extension Term {
    @available(*, unavailable, message: "Use WriteStream.stdout instead")
    public static var stdout: WriteStream { return WriteStream.stdout }
    
    @available(*, unavailable, message: "Use WriteStream.stderr instead")
    public static var stderr: WriteStream { return WriteStream.stderr }
}

@available(*, unavailable, message: "use CLI.Error instead")
