         executeAfterSetup {
             
             if let albumsFetchResult = self.albumsFetchResult,
-               let changes = changeInfo.changeDetails(for: albumsFetchResult)
+               let changes = changeInfo.changeDetails(for: albumsFetchResult.phFetchResult)
             {
-                self.albumsFetchResult = changes.fetchResultAfterChanges
-                self.onAlbumsChange?(self.albums())
+                PhotoLibraryFetchResult.create(with: { changes.fetchResultAfterChanges }) { albumsFetchResult in
+                    self.albumsFetchResult = albumsFetchResult
+                    self.onAlbumsChange?(albumsFetchResult.albums)
+                }
             }
             
             if let observedAlbum = self.observedAlbum,

    func observeAlbums(handler: @escaping ([PhotoLibraryAlbum]) -> ()) {
        executeAfterSetup {
            self.onAlbumsChange = handler
            handler(self.albums())
        }
    }
    

        )
    }
}

private final class PhotoLibraryFetchResult {
    
    // MARK: - Data
    let albums: [PhotoLibraryAlbum]
    let phFetchResult: PHFetchResult<PHAssetCollection>
    
    private static let setupQueue = DispatchQueue(
        label: "ru.avito.Paparazzo.PhotoLibraryFetchResult.setupQueue",
        qos: .userInitiated
    )
    
    // MARK: - Init
    
    /// Use `PhotoLibraryFetchResult.create` to create an instance
    private init(phFetchResult: PHFetchResult<PHAssetCollection>?) {
        assert(!Thread.isMainThread, "Do not call this method on main thread")
        
        let options = PhotoLibraryFetchResult.phFetchOptions()
        
        self.phFetchResult = phFetchResult ?? PHAssetCollection.fetchAssetCollections(
            with: .album,
            subtype: .any,
            options: options
        )
        
        self.albums = PhotoLibraryFetchResult.albums(from: self.phFetchResult, options: options)
    }
    
    // MARK: - Private
    
    static func create(
        with phFetchResult: (() -> PHFetchResult<PHAssetCollection>)? = nil,
        completion: @escaping (PhotoLibraryFetchResult) -> ())
    {
        setupQueue.async {
            let fetchResult = PhotoLibraryFetchResult(phFetchResult: phFetchResult?())
            DispatchQueue.main.async {
                completion(fetchResult)
            }
        }
    }
    
    private static func albums(
        from phFetchResult: PHFetchResult<PHAssetCollection>,
        options: PHFetchOptions?)
        -> [PhotoLibraryAlbum]
    {
        assert(!Thread.isMainThread, "Do not call this method on main thread")
        
        let allPhotosStartDate = Date()
        let allPhotosFetchResult = PHAsset.fetchAssets(with: .image, options: options)
        print("All photos fetch took \(Date().timeIntervalSince(allPhotosStartDate))")
        
        var albums = [
            PhotoLibraryAlbum(
                identifier: "ru.avito.Paparazzo.PhotoLibraryAlbum.identifier.allPhotos",
                title: localized("All photos"),
                coverImage: allPhotosFetchResult.lastObject.flatMap { PHAssetImageSource(asset: $0) },
                fetchResult: allPhotosFetchResult
            )
        ]
        
        phFetchResult.enumerateObjects(using: { album, _, _ in
            
            let startDate = Date()
            let albumAssetsFetchResult = PHAsset.fetchAssets(in: album, options: options)
            print("\(album.localizedTitle) fetch took \(Date().timeIntervalSince(startDate))")
            
            albums.append(PhotoLibraryAlbum(
                identifier: album.localIdentifier,
                title: album.localizedTitle,
                coverImage: albumAssetsFetchResult.lastObject.flatMap { PHAssetImageSource(asset: $0) },
                fetchResult: albumAssetsFetchResult
            ))
        })
        
        return albums
    }
    
    private static func phFetchOptions() -> PHFetchOptions? {
        if #available(iOS 9.0, *) {
            let options = PHFetchOptions()
            options.includeAssetSourceTypes = [.typeUserLibrary, .typeCloudShared, .typeiTunesSynced]
            return options
        } else {
            return nil
        }
    }
}

final class PhotoLibraryAlbum: Equatable {
    
    let identifier: String
    let title: String?
    let coverImage: ImageSource?
    
    fileprivate var fetchResult: PHFetchResult<PHAsset>
    
    fileprivate init(identifier: String, title: String?, coverImage: ImageSource?, fetchResult: PHFetchResult<PHAsset>) {
        self.identifier = identifier
        self.title = title
        self.coverImage = coverImage
        self.fetchResult = fetchResult
    }
    
    static func ==(lhs: PhotoLibraryAlbum, rhs: PhotoLibraryAlbum) -> Bool {
        return lhs.identifier == rhs.identifier
    }
}
