         self.parser = parser
         self.keepAlive = keepAlive
     }
-}
-
-extension Client {
-    private func addHeaders(request: inout Request) {
+
+    public convenience init(uri: String, verifyBundle: String? = nil, certificate: String? = nil, privateKey: String? = nil, certificateChain: String? = nil, serializer: S4.RequestSerializer = RequestSerializer(), parser: S4.ResponseParser = ResponseParser(), keepAlive: Bool = false) throws {
+        try self.init(uri: URI(uri), verifyBundle: verifyBundle, certificate: certificate, privateKey: privateKey, certificateChain: certificateChain, serializer: serializer, parser: parser, keepAlive: keepAlive)
+    }
+}
+
+extension Client {
+    private func addHeaders(_ request: inout Request) {
         var request = request
         request.host = "\(host):\(port)"
         request.userAgent = "Zewo"

// SOFTWARE.

@_exported import TCPSSL
@_exported import HTTP
@_exported import HTTPParser
@_exported import HTTPSerializer

public final class Client: Responder {
    public let host: String

}

extension Client {
    public func send(method: Method, uri: String, headers: Headers = [:], body: Data = [], middleware: Middleware...) throws -> Response {
        return try send(method: method, uri: uri, headers: headers, body: body, middleware: middleware)
    }

    public func send(method: Method, uri: String, headers: Headers = [:], body: DataConvertible, middleware: Middleware...) throws -> Response {
        return try send(method: method, uri: uri, headers: headers, body: body, middleware: middleware)
    }
}

extension Client {
    public func get(_ uri: String, headers: Headers = [:], body: Data = [], middleware: Middleware...) throws -> Response {
        return try send(method: .get, uri: uri, headers: headers, body: body, middleware: middleware)
    }

    public func get(_ uri: String, headers: Headers = [:], body: DataConvertible, middleware: Middleware...) throws -> Response {
        return try send(method: .get, uri: uri, headers: headers, body: body, middleware: middleware)
    }
}

extension Client {
    public func post(_ uri: String, headers: Headers = [:], body: Data = [], middleware: Middleware...) throws -> Response {
        return try send(method: .post, uri: uri, headers: headers, body: body, middleware: middleware)
    }

    public func post(_ uri: String, headers: Headers = [:], body: DataConvertible, middleware: Middleware...) throws -> Response {
        return try send(method: .post, uri: uri, headers: headers, body: body, middleware: middleware)
    }
}

extension Client {
    public func put(_ uri: String, headers: Headers = [:], body: Data = [], middleware: Middleware...) throws -> Response {
        return try send(method: .put, uri: uri, headers: headers, body: body, middleware: middleware)
    }

    public func put(_ uri: String, headers: Headers = [:], body: DataConvertible, middleware: Middleware...) throws -> Response {
        return try send(method: .put, uri: uri, headers: headers, body: body, middleware: middleware)
    }
}

extension Client {
    public func patch(_ uri: String, headers: Headers = [:], body: Data = [], middleware: Middleware...) throws -> Response {
        return try send(method: .patch, uri: uri, headers: headers, body: body, middleware: middleware)
    }

    public func patch(_ uri: String, headers: Headers = [:], body: DataConvertible, middleware: Middleware...) throws -> Response {
        return try send(method: .patch, uri: uri, headers: headers, body: body, middleware: middleware)
    }
}

extension Client {
    public func delete(_ uri: String, headers: Headers = [:], body: Data = [], middleware: Middleware...) throws -> Response {
        return try send(method: .delete, uri: uri, headers: headers, body: body, middleware: middleware)
    }

    public func delete(_ uri: String, headers: Headers = [:], body: DataConvertible, middleware: Middleware...) throws -> Response {
        return try send(method: .delete, uri: uri, headers: headers, body: body, middleware: middleware)
    }
}

extension Client {
    private func send(method: Method, uri: String, headers: Headers = [:], body: Data = [], middleware: [Middleware]) throws -> Response {
        let request = try Request(method: method, uri: URI(uri), headers: headers, body: body)
        return try send(request, middleware: middleware)
    }

    private func send(method: Method, uri: String, headers: Headers = [:], body: DataConvertible, middleware: [Middleware]) throws -> Response {
        let request = try Request(method: method, uri: URI(uri), headers: headers, body: body.data)
        return try send(request, middleware: middleware)
    }
}

extension Request {
    public var connection: Header {
        get {
            return headers["Connection"] ?? []
        }

        set(connection) {
            headers["Connection"] = connection
        }
    }

    var host: String? {
        get {
            return headers["Host"].first
        }

        set(host) {
            headers["Host"] = host.map({Header($0)}) ?? []
        }
    }

    typealias Upgrade = (Response, Stream) throws -> Void

    // Warning: The storage key has to be in sync with Zewo.HTTP's upgrade property.
    var upgrade: Upgrade? {
        get {
            return storage["request-connection-upgrade"] as? Upgrade
        }

        set(upgrade) {
            storage["request-connection-upgrade"] = upgrade
        }
    }

    var userAgent: String? {
        get {
            return headers["User-Agent"].first
        }
        
        set(userAgent) {
            headers["User-Agent"] = userAgent.map({Header($0)}) ?? []
        }
    }
}
