     }
 }
 
+public struct PhotoLibraryFetchResultDataSource {
+    public private(set) var fetchResult: PHFetchResult<PHObject>
+    public private(set) var objects: [PHObject]
+}
+
 @objc(PhotoLibraryDelegate)
 public protocol PhotoLibraryDelegate {
     /**

        prepare()
    }
    
    /**
     Fetch all the PHAssetCollections asynchronously based on a type and subtype.
     - Parameter type: A PHAssetCollectionType.
     - Parameter subtype: A PHAssetCollectionSubtype.
     - Parameter completion: A completion block.
     */
    public func fetchAssetCollections(with type: PHAssetCollectionType, subtype: PHAssetCollectionSubtype, completion: ([PhotoLibraryDataSource]) -> Void) {
        self.type = type
        self.subtype = subtype
        
        DispatchQueue.global(qos: .default).async { [weak self, type = type, subtype = subtype, completion = completion] in
            guard let s = self else {
                return
            }
            
            defer {
                DispatchQueue.main.async { [weak self] in
                    guard let s = self else {
                        return
                    }
                    completion(s.collections)
                }
            }
            
            let options = PHFetchOptions()
            options.includeHiddenAssets = true
            options.includeAllBurstAssets = true
            options.wantsIncrementalChangeDetails = true
            
            s.collectionFetchResult = PHAssetCollection.fetchAssetCollections(with: type, subtype: subtype, options: options)
            
            s.collectionFetchResult?.enumerateObjects(options: [.concurrent]) { [weak self] (collection, _, _) in
                guard let s = self else {
                    return
                }
                
                let options = PHFetchOptions()
                let descriptor = NSSortDescriptor(key: "creationDate", ascending: false)
                options.sortDescriptors = [descriptor]
                options.includeHiddenAssets = true
                options.includeAllBurstAssets = true
                options.wantsIncrementalChangeDetails = true
                
                s.fetchAssets(in: collection, options: options) { [weak self] (assets, fetchResult) in
                    guard let s = self else {
                        return
                    }
                    s.collections.append(PhotoLibraryDataSource(fetchResult: fetchResult, collection: collection, assets: assets))
                }
            }
        }
    }
    
    /**
     Performes an asynchronous change to the PHPhotoLibrary database.


@objc(PhotoLibrary)
public class PhotoLibrary: NSObject {
    /// A reference to the PHCachingImageManager.
    public private(set) lazy var cachingImageManager = PHCachingImageManager()
    
    /// A reference to all current PHFetchResults.
    public private(set) lazy var fetchResults = [PhotoLibraryFetchResultDataSource]()
    
    /// The assets used in the album.
    public private(set) var collections = [PhotoLibraryDataSource]() {
        willSet {
            guard .authorized == authorizationStatus else {
                return
