 public class NSURLSessionImageDownloader: ImageDownloader {
 
     public func downloadImageAndSet(on imageView: UIImageView, with imageURL: NSURL, onCompletion completionHandler: ((image: UIImage, url: NSURL) -> Void)) {
-        self.downloadImage(with: imageURL) { (image, url) in
-            guard imageURL == url else {
-                return
-            }
-
-            NSOperationQueue.mainQueue().addOperationWithBlock {
-                imageView.image = image
-                completionHandler(image: image, url: url)
-            }
-        }
+        _downloadImageAndSet(self, on: imageView, with: imageURL, onCompletion: completionHandler)
     }
 
     public func downloadImage(with imageURL: NSURL, onCompletion completionHandler: ((image: UIImage, url: NSURL) -> Void)) {

public extension ImageDownloader {

    func downloadImageAndSet(on imageView: UIImageView, with imageURL: NSURL, onCompletion completionHandler: ((image: UIImage, url: NSURL) -> Void)) {
        self.downloadImage(with: imageURL) { (image, url) in
            guard imageURL == url else {
                return
            }

            NSOperationQueue.mainQueue().addOperationWithBlock {
                imageView.image = image
                completionHandler(image: image, url: url)
            }
        }
    }

}


import UIKit

private func _downloadImageAndSet(imageDownloader: ImageDownloader, on imageView: UIImageView, with imageURL: NSURL, onCompletion completionHandler: ((image: UIImage, url: NSURL) -> Void)) {
    
    imageDownloader.downloadImage(with: imageURL) { (image, url) in
        guard imageURL == url else {
            return
        }

        NSOperationQueue.mainQueue().addOperationWithBlock {
            imageView.image = image
            completionHandler(image: image, url: url)
        }
    }

}

// Mark: - Image Downloader
public protocol ImageDownloader: class {
    func downloadImage(with imageURL: NSURL, onCompletion completionHandler: ((image: UIImage, url: NSURL) -> Void))
