   public func deferredDataTask(qos: DispatchQoS = .current,
                                with request: URLRequest) -> DeferredURLSessionTask<(Data, HTTPURLResponse)>
   {
-    let tbd = DeferredURLSessionTask<(Data, HTTPURLResponse)>(qos: qos)
-    tbd.urlSessionTask = dataTask(with: request, completionHandler: dataCompletion(tbd))
-    return tbd
+    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,

  case InvalidState
}

public class DeferredURLSessionTask<Value>: TBD<Value>
{
  private weak var task: URLSessionTask? = nil

  init(qos: DispatchQoS)
  {
    let queue = DispatchQueue(label: "urlsession", qos: qos)
    super.init(queue: queue)
  }

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

    // try to propagate the cancellation upstream
    task.cancel()
    // task.state == .canceling (checking would be nice, but that would require sleeping the thread)
    return true
  }

  public fileprivate(set) var urlSessionTask: URLSessionTask? {
    get {
      // is this thread-safe, or is a capture-and-return necessary?
      return task
    }
    set {
      task = newValue
    }
  }

  public override func enqueue(queue: DispatchQueue? = nil, boostQoS: Bool = true, task: @escaping (Determined<Value>) -> Void)
  {
    if state == .waiting
    {
      urlSessionTask?.resume()
      beginExecution()
    }
    super.enqueue(queue: queue, boostQoS: boostQoS, task: task)
  }
}

public extension URLSession
{
  private func dataCompletion(_ tbd: DeferredURLSessionTask<(Data, HTTPURLResponse)>) -> (Data?, URLResponse?, Error?) -> Void
  {
    return {
      (data: Data?, response: URLResponse?, error: Error?) in
      if let error = error
      {
        tbd.determine(error)

  public func deferredDownloadTask(qos: DispatchQoS = .current,
                                   withResumeData data: Data) -> DeferredURLSessionTask<(URL, FileHandle, HTTPURLResponse)>
  {
    let tbd = TBD<(URL, FileHandle, HTTPURLResponse)>(qos: qos)

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
    let task = downloadTask(withResumeData: data, completionHandler: downloadCompletion(tbd))
    return DeferredDownloadTask(source: tbd, task: task)
#else // swift-corelibs-foundation calls fatalError() when downloadTask(withResumeData:) is called
    // let task = downloadTask(withResumeData: data, completionHandler: downloadCompletion(tbd))
    tbd.cancel(.invalid("swift-corelibs-foundation does not support \(#function)"))
    return DeferredDownloadTask(source: tbd, task: URLSessionDownloadTask())
#endif
  }
}
