   public func deferredDownloadTask(qos: DispatchQoS = .current,
                                    with request: URLRequest) -> DeferredURLSessionTask<(URL, FileHandle, HTTPURLResponse)>
   {
-    let tbd = DeferredDownloadTask<(URL, FileHandle, HTTPURLResponse)>(qos: qos)
-    tbd.urlSessionTask = downloadTask(with: request, completionHandler: downloadCompletion(tbd))
-    return tbd
+    let tbd = TBD<(URL, FileHandle, HTTPURLResponse)>(qos: qos)
+    let task = downloadTask(with: request, completionHandler: downloadCompletion(tbd))
+    return DeferredDownloadTask(source: tbd, task: task)
   }
 
   public func deferredDownloadTask(qos: DispatchQoS = .current,

  @discardableResult
  override func cancel(_ reason: String = "") -> Bool
  {
    guard !self.isDetermined,
          let task = urlSessionTask as? URLSessionDownloadTask
    else { return super.cancel(reason) }

    // try to propagate the cancellation upstream
    task.cancel(byProducingResumeData: { _ in }) // Let the completion handler collect the data for resuming.
    // task.state == .canceling (checking would be nice, but that would require sleeping the thread)
    return true
  }
}

extension URLSession
{
  private func downloadCompletion(_ tbd: DeferredURLSessionTask<(URL, FileHandle, HTTPURLResponse)>) -> (URL?, URLResponse?, Error?) -> Void
  {
    return {
      (url: URL?, response: URLResponse?, error: Error?) in
      if let error = error
      {
        if let error = error as? URLError, error.code == .cancelled
        {
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
          let URLSessionDownloadTaskResumeData = NSURLSessionDownloadTaskResumeData
#endif
          if let data = error.userInfo[URLSessionDownloadTaskResumeData] as? Data

  public func deferredDataTask(qos: DispatchQoS = .current,
                               with request: URLRequest) -> DeferredURLSessionTask<(Data, HTTPURLResponse)>
  {
    let tbd = TBD<(Data, HTTPURLResponse)>(qos: qos)
    let task = dataTask(with: request, completionHandler: dataCompletion(tbd))
    return DeferredURLSessionTask(source: tbd, task: task)
  }

  public func deferredDataTask(qos: DispatchQoS = .current,
