     }
 }
 
+extension HTTPClient {
+    private func bodyFromResponse(response: Response, forRequest request: HTTPRequest) throws -> AnyObject {
+        if response.statusCode / 100 != 2 {
+            throw Error.statusCode(response.statusCode, response: response.debugDescription)
+        }
+        
+        guard let contentType = response.headers.contentType else {
+            return response.data
+        }
+        
+        if let expectedContentType = request.headers.accept  where expectedContentType != contentType {
+            throw Error.contentTypeMismatch(expected: expectedContentType.rawValue, received: contentType.rawValue)
+        }
+        
+        switch contentType {
+        case .json:
+            return try NSJSONSerialization.JSONObjectWithData(response.data, options: NSJSONReadingOptions(rawValue: 0))
+            
+        case .html, .text:
+            return String(data: response.data, encoding: NSUTF8StringEncoding) ?? response.data
+        }
+    }
+}
+
 private class HTTPSessionDelegate: NSObject {
     private var taskContexts: [Int : Context] = [:]
     var logger: HTTPClientLogger?

        self.session = sessionFactory.sessionWithDelegate(self.sessionDelegate)
        self.requestTransformer = requestTransformer
    }
}

// MARK: execute request
extension HTTPClient {
    public func execute(request: HTTPRequest, completion: RequestResult -> Void) {
        var request = request
        if let requestPreProcessor = self.requestPreProcessor {

        let task = self.session.dataTaskWithRequest(request)
        self.sessionDelegate.startTask(task, completion: completion)
    }

    // MARK: execute query
    public func execute<Q: HTTPQuery, T where T == Q.Result, T: ConvertibleFromRaw>(query: Q, completion: (HTTPClientQueryResult<T>) -> ()) {
        let request = query.request
        
