                 objc_setAssociatedObject(self, &dataTaskCompletionHandlerKey, Box(value), UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
             } else {
                 objc_setAssociatedObject(self, &dataTaskCompletionHandlerKey, nil, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
+            }
+        }
+    }
+}
+
+extension NSURLSessionDownloadTask {
+    private var request: Any? {
+        get {
+            return (objc_getAssociatedObject(self, &taskRequestKey) as? Box<Any>)?.unbox
+        }
+        
+        set {
+            if let value = newValue {
+                objc_setAssociatedObject(self, &taskRequestKey, Box(value), UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
+            } else {
+                objc_setAssociatedObject(self, &taskRequestKey, nil, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
             }
         }
     }

            }
        }
    }
}

private extension NSURLSessionDataTask {
    private var responseBuffer: NSMutableData {
        if let responseBuffer = objc_getAssociatedObject(self, &dataTaskResponseBufferKey) as? NSMutableData {
            return responseBuffer

    public class func cancelRequest<T: Request>(requestType: T.Type, URLSession: NSURLSession, passingTest test: T -> Bool = { r in true }) {
        URLSession.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in
            let tasks = (dataTasks + uploadTasks + downloadTasks).filter { task in
                var request: T?
                switch task {
                case let x as NSURLSessionDataTask:
                    request = x.request as? T
                    
                case let x as NSURLSessionDownloadTask:
                    request = x.request as? T
                    
                default:
                    break
                }
                
                if let request = request {
                    return test(request)
                } else {
                    return false
