         return components.map { "\($0)=\($1)" }.joined(separator: "&")
     }
 }
-
-extension NSNumber {
-    fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) }
-}


extension URLRequest {
    public init?(method: HTTPMethod, url: String, parameters: [String: Any]?) {
        var body: Data?
        if let parameters = parameters {
            body = URLRequest.query(parameters).data(using: String.Encoding.utf8, allowLossyConversion: false)
        }
        self.init(method: method.rawString, url: url, body: body)
    }
    public init?(method: String, url: String, body: Data?) {
        guard let url = URL(string: url) else { return nil }

        self.allowsCellularAccess = true
        self.httpMethod = method
        [
            // Content-Type and Accept below
            // Content-Type will be set automatic
            // "application/x-www-form-urlencoded", "charset=utf-8", "multipart/form-data", "application/json", "text/xml"
            // example:
            // "*/*": "Accept"
            // "application/x-www-form-urlencoded": "Content-Type"
            ].forEach { (key, value) in
                self.addValue(key, forHTTPHeaderField: value)
        }
        self.httpBody = body
        self.httpShouldHandleCookies = true
        self.httpShouldUsePipelining = true
    }
}

// MARK: - parameter query, copy from alamofire
extension NSNumber {
    fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) }
}

extension URLRequest {
    private static func escape(_ string: String) -> String {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
