 private class TaskQueue {
     var pendingTasks = NSMutableOrderedSet()
     var executingTasks = Set<NSURLSessionTask>()
-    var maxExecutingTaskCount = 1
+    var maxExecutingTaskCount = 8
     
     func resume(task: NSURLSessionTask) {
         if !self.pendingTasks.containsObject(task) && !self.executingTasks.contains(task) {


// MARK: - ImageLoading

/** Performs loading of images for the given tasks.
*/
public protocol ImageLoading: class {
    /** Manager that controls image loading.
     */
    weak var manager: ImageLoadingManager? { get set }
    
    /** Resumes loading for the given task.
     */
    func resumeLoadingFor(task: ImageTask)
    
    /** Suspends loading for the given task.
     */
    func suspendLoadingFor(task: ImageTask)
    
    /** Cancels loading for the given task.
     */
    func cancelLoadingFor(task: ImageTask)
    
    /** Compares requests for equivalence with regard to caching output images. This method is used for memory caching, in most cases there is no need for filtering out the dynamic part of the request (is there is any).
     */
    func isCacheEquivalent(lhs: ImageRequest, to rhs: ImageRequest) -> Bool
    
    /** Invalidates the receiver. This method gets called by the manager when it is invalidated.
     */
    func invalidate()
    
    /** Clears the receiver's cache storage (if any).
     */
    func removeAllCachedImages()
}

// MARK: - ImageLoadingDelegate

/** Manages image loading.
*/
public protocol ImageLoadingManager: class {
    /** Sent periodically to notify the manager of the task progress.
     */
    func loader(loader: ImageLoading, task: ImageTask, didUpdateProgress progress: ImageTaskProgress)
    
    /** Sent when loading for the task is completed.
     */
    func loader(loader: ImageLoading, task: ImageTask, didCompleteWithImage image: Image?, error: ErrorType?, userInfo: Any?)
}

// MARK: - ImageLoaderConfiguration

public struct ImageLoaderConfiguration {
    public var dataLoader: ImageDataLoading
    public var decoder: ImageDecoding
    
    /** Maximum number of concurrent executing NSURLSessionTasks. Default value is 10.
     */
    public var maxConcurrentDataTaskCount = 10
    
    /** Image decoding queue. Default queue has a maximum concurrent operation count 1.
     */
    public var decodingQueue = NSOperationQueue(maxConcurrentOperationCount: 1)
    
    /** Image processing queue. Default queue has a maximum concurrent operation count 2.
     */
    public var processingQueue = NSOperationQueue(maxConcurrentOperationCount: 2)

    /** Determines whether the image loader should reuse NSURLSessionTasks for equivalent image requests. Default value is true.
     */
    public var taskReusingEnabled = true

    @available(*, deprecated=2.2)
    public var congestionControlEnabled = true
    

    public init(configuration: ImageLoaderConfiguration, delegate: ImageLoaderDelegate = ImageLoaderDefaultDelegate()) {
        self.configuration = configuration
        self.delegate = delegate
        self.taskQueue.maxExecutingTaskCount = configuration.maxConcurrentSessionTaskCount
    }

    public func resumeLoadingFor(task: ImageTask) {
        // Image loader performs all tasks asynchronously on its serial queue.
        dispatch_async(self.queue) {
            // DataTask wraps NSURLSessionTask
            // ImageLoader reuses DataTasks for equivalent requests
            let key = ImageRequestKey(task.request, owner: self)
            var dataTask: DataTask! = self.reuseTasks ? self.dataTasks[key] : nil
            if dataTask == nil {
                dataTask = self.dataTaskWith(task.request, key: key)
                if self.reuseTasks {
