   }
   
   func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
+    
+    guard let response = downloadTask.response as? NSHTTPURLResponse else { return }
+    
+    if let asset = assetsDownloadingByTaskIdentifier[downloadTask.taskIdentifier] {
+      do {
+        try verifyResponse(response, forAsset: asset)
+      } catch let error {
+        self.cancelAndFailWithError(error)
+      }
+    }
   }
 
   func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {

  }
  
  private func cancelAndFailWithReason(reason: String, underlyingError: ErrorType? = nil) {
    cancel()
    
    let error = WebAppError.DownloadFailure(reason: reason, underlyingError: underlyingError)
    delegate?.assetBundleDownloader(self, didFailWithError: error)
  }
  

      }
    }
  }
  
  private func verifyResponse(response: NSHTTPURLResponse, forAsset asset: Asset) throws {
    // A response with a non-success status code should not be considered a succesful download
    if !(200..<300).contains(response.statusCode) {
      throw WebAppError.DownloadFailure(reason: "Non-success status code for asset: \(asset)", underlyingError: nil)
      // If we have a hash for the asset, and the ETag header also specifies
      // a hash, we compare these to verify if we received the expected asset version
    } else if let expectedHash = asset.hash,
      let ETag = response.allHeaderFields["ETag"] as? String,
      let actualHash = SHA1HashFromETag(ETag)
      where actualHash != expectedHash {
        throw WebAppError.DownloadFailure(reason: "Hash mismatch for asset: \(asset)", underlyingError: nil)
    }
  }
}
