     case Cancelled(url: NSURL)
 }
 
+// MARK: - Task Tracking
+final public class TrackingToken: Hashable {
+    public var hashValue: Int {
+        return "\(unsafeAddressOf(self))".hashValue
+    }
+}
+
+public func ==(lhs: TrackingToken, rhs: TrackingToken) -> Bool {
+    return lhs === rhs
+}
+
+public protocol TaskTracker: class {
+    var progressInfo: ProgressInfo? { get }
+    
+    func addTracking(progress progress: DownloadProgressHandler?, completion: DownloadCompletionHandler?) -> TrackingToken?
+    func removeTracking(token: TrackingToken?)
+}
+
+
+// Task
 public protocol Task: class {
     var cancelled: Bool { get }
     func cancel()
 }
 
+
+// MARK: downloader
 public protocol Downloader: class {
     func download(url: NSURL, progress: DownloadProgressHandler?, completion: DownloadCompletionHandler) -> Task
     func download(url: NSURL, cache: Cache?, progress: DownloadProgressHandler?, completion: DownloadCompletionHandler) -> Task
+    
     func download(url: NSURL, taskGenerator: TaskGenerator?, cache: Cache?, progress: DownloadProgressHandler?, completion: DownloadCompletionHandler) -> Task
+    
+    func trackerForTask(task: Task) -> TaskTracker?
+    
 }
 
 public extension Downloader {

    
}


final private class URLSessionDelegate: NSObject, NSURLSessionDownloadDelegate {
    private var queue: dispatch_queue_t

        return session
    }()
    
    private var tasks: [String: TaskTracker] = [:]
    private var lock = OS_SPINLOCK_INIT
    
    private var taskGenerator: TaskGenerator!
    
    public init(taskGenerator: TaskGenerator? = nil) {
