         resultHandler: T? -> ())
         -> ImageRequestID
     {
+        if let previewImage = previewImage where options.deliveryMode == .Progressive {
+            if NSThread.isMainThread() {    // нужно вернуть результат как можно быстрее
+                resultHandler(T(CGImage: previewImage))
+            } else {
+                dispatch_async(dispatch_get_main_queue()) {
+                    resultHandler(T(CGImage: previewImage))
+                }
+            }
+        }
+        
         switch options.size {
         case .FullResolution:
             return requestFullResolutionImage(deliveryMode: options.deliveryMode, resultHandler: resultHandler)


public final class UrlImageSource: ImageSource {
    
    private static let processingQueue = dispatch_queue_create(
        "ru.avito.AvitoMediaPicker.UrlImageSource.processingQueue",
        dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INITIATED, 0)
    )

    private let url: NSURL
    private let previewImage: SingleObjectCache<CGImageWrapper>?

    public init(url: NSURL, previewImage: CGImage? = nil) {
        self.url = url
        self.previewImage = previewImage.flatMap { SingleObjectCache(value: CGImageWrapper(CGImage: $0)) }
    }

    // MARK: - ImageSource
    
    public func fullResolutionImageData(completion: NSData? -> ()) {
        dispatch_async(UrlImageSource.processingQueue) { [url] in
            let data = NSData(contentsOfURL: url)
            dispatch_async(dispatch_get_main_queue()) {
                completion(data)

        resultHandler: T? -> ())
        -> ImageRequestID
    {
        UrlImageSource.processingQueue.addOperationWithBlock { [url] in
            
            let source = CGImageSourceCreateWithURL(url, nil)
            
