     ///
     /// - parameters:
     ///       - data: the data to write
-    /// - returns: the future which will be notified once the operation completes.
-    func write(_ data: NIOAny) -> EventLoopFuture<Void>
-
-    /// Write data to the remote peer.
-    ///
-    /// Be aware that to be sure that data is really written to the remote peer you need to call `flush` or use `writeAndFlush`.
-    /// Calling `write` multiple times and then `flush` may allow the `Channel` to `write` multiple data objects to the remote peer with one syscall.
-    ///
-    /// - parameters:
-    ///       - data: the data to write
     ///       - promise: the `EventLoopPromise` that will be notified once the operation completes,
     ///                  or `nil` if not interested in the outcome of the operation.
     func write(_ data: NIOAny, promise: EventLoopPromise<Void>?)

    /// Bind to a `SocketAddress`.
    /// - parameters:
    ///       - to: the `SocketAddress` to which we should bind the `Channel`.
    /// - returns: the future which will be notified once the operation completes.
    func bind(to: SocketAddress) -> EventLoopFuture<Void>

    /// Bind to a `SocketAddress`.
    /// - parameters:
    ///       - to: the `SocketAddress` to which we should bind the `Channel`.
    ///       - promise: the `EventLoopPromise` that will be notified once the operation completes,
    ///                  or `nil` if not interested in the outcome of the operation.
    func bind(to: SocketAddress, promise: EventLoopPromise<Void>?)

    /// Connect to a `SocketAddress`.
    /// - parameters:
    ///       - to: the `SocketAddress` to which we should connect the `Channel`.
    /// - returns: the future which will be notified once the operation completes.
    func connect(to: SocketAddress) -> EventLoopFuture<Void>

    /// Connect to a `SocketAddress`.
    /// - parameters:

    var eventLoop: EventLoop { get }
}

/// Extra `ChannelOutboundInvoker` methods. Each method that returns a `EventLoopFuture` will just do the following:
///     - create a new `EventLoopPromise<Void>`
///     - call the corresponding method that takes a `EventLoopPromise<Void>`
///     - return `EventLoopPromise.futureResult`
extension ChannelOutboundInvoker {

    /// Register on an `EventLoop` and so have all its IO handled.
    ///
    /// - returns: the future which will be notified once the operation completes.
    public func register(file: StaticString = #file, line: UInt = #line) -> EventLoopFuture<Void> {
        let promise = makePromise(file: file, line: line)
        register(promise: promise)
        return promise.futureResult
    }

    /// Bind to a `SocketAddress`.
    /// - parameters:
    ///       - to: the `SocketAddress` to which we should bind the `Channel`.
    /// - returns: the future which will be notified once the operation completes.
    public func bind(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture<Void> {
        let promise = makePromise(file: file, line: line)
        bind(to: address, promise: promise)
        return promise.futureResult
    }

    /// Connect to a `SocketAddress`.
    /// - parameters:
    ///       - to: the `SocketAddress` to which we should connect the `Channel`.
    /// - returns: the future which will be notified once the operation completes.
    public func connect(to address: SocketAddress, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture<Void> {
        let promise = makePromise(file: file, line: line)
        connect(to: address, promise: promise)
        return promise.futureResult
    }

    /// Write data to the remote peer.
    ///
    /// Be aware that to be sure that data is really written to the remote peer you need to call `flush` or use `writeAndFlush`.
    /// Calling `write` multiple times and then `flush` may allow the `Channel` to `write` multiple data objects to the remote peer with one syscall.
    ///
    /// - parameters:
    ///       - data: the data to write
    /// - returns: the future which will be notified once the operation completes.
    public func write(_ data: NIOAny, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture<Void> {
        let promise = makePromise(file: file, line: line)
        write(data, promise: promise)
        return promise.futureResult
    }

    /// Shortcut for calling `write` and `flush`.
    ///
    /// - parameters:
    ///       - data: the data to write
    /// - returns: the future which will be notified once the `write` operation completes.
    public func writeAndFlush(_ data: NIOAny, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture<Void> {
        let promise = makePromise(file: file, line: line)
        writeAndFlush(data, promise: promise)
        return promise.futureResult
    }

    /// Close the `Channel` and so the connection if one exists.
    ///
    /// - parameters:
    ///       - mode: the `CloseMode` that is used
    /// - returns: the future which will be notified once the operation completes.
    public func close(mode: CloseMode = .all, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture<Void> {
        let promise = makePromise(file: file, line: line)
        close(mode: mode, promise: promise)
        return promise.futureResult
    }

    /// Trigger a custom user outbound event which will flow through the `ChannelPipeline`.
    ///
    /// - parameters:
    ///       - event: the event itself.
    /// - returns: the future which will be notified once the operation completes.
    public func triggerUserOutboundEvent(_ event: Any, file: StaticString = #file, line: UInt = #line) -> EventLoopFuture<Void> {
        let promise = makePromise(file: file, line: line)
        triggerUserOutboundEvent(event, promise: promise)
        return promise.futureResult
    }
