     case connect = "CONNECT"
 }
 
+/// A type that represents an HTTP Body.
+///
+/// A `Body` is used by `Request` to create an `URLRequest`.
+///
+/// Adopted by `Data` and `String`.
+/// - seealso: `FormEncodedBody`, `JSONEncodedBody`.
 public protocol Body {
+    
+    /// Returns HTTP Header parameters required for `self`, if any.
+    ///
+    /// This is usally a "Content-Type" header like "application/json" for a
+    /// JSON encoded Body.
+    ///
+    /// Defaults to `nil`.
     var header: Parameters? { get }
+    
+    /// The body data that should be sent in an HTTP request.
     var requestData: Data { get }
 }
 

    }
}

public struct JSONEncodedBody: Body {
    public let requestData: Data
    
    public init(jsonObject: Any) throws {
        requestData = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
    }
    
    public var header: Parameters? {
        return [ "Content-Type" : "application/json" ]
    }
}

public protocol URLRequestEncodable: CustomDebugStringConvertible {
    var urlRequest: URLRequest { get }
}

extension URLRequestEncodable {
    public var debugDescription: String {
        return cURLRepresentation
    }
}

public struct Request: URLRequestEncodable {
    public var method: HTTPMethod
    public var url: URL
    public var header: Parameters?
    public var body: Body?
    
    public init(_ method: HTTPMethod, _ path: String?=nil, query: Parameters?=nil, header: Parameters?=nil, body: Body?=nil) {
        self.init(method, url: URL(path: path, query: query), header: header, body: body)
    }
    
    public init(_ method: HTTPMethod, url: URL, header: Parameters?=nil, body: Body?=nil) {
        self.method = method
        self.header = header

}

public extension URLRequest {
    
    /// Adds or replaces all header fields with the given values.
    ///
    /// - note: If a value was previously set for the given header
    /// field, that value is replaced.
    mutating func apply(header: Parameters?) {
        header?.forEach { setValue($1, forHTTPHeaderField: $0) }
    }
}

public extension URL {
    
    /// `true` if `self` has no scheme.
    ///
    /// - note: Used by `BaseClient.encode` to determine if a `URLRequest` should be
    /// encoded using `self` alone (when `false`) or in combination with
    /// its `baseURL` (when `true`).
    var isRelative: Bool {
        return scheme == nil
    }
    
    /// Creates a relative URL with a given `path` and `query` Dictionary.
    init(path: String?, query: Parameters?) {
        var components = URLComponents()
        components.path = path ?? ""
