     }
 
     @objc static func keyPathsForValuesAffectingUserInfo() -> Set<String> {
-        return [ "original.userInfo" ]
+        return [ #keyPath(original.userInfo) ]
     }
 
     override var userInfo: [ProgressUserInfoKey : Any] {


// MARK: - Backports

private struct KVO {
    static var context = false
    enum KeyPath: String {
        case completedUnitCount
        case totalUnitCount
        case localizedDescription
        case localizedAdditionalDescription
        case cancellable
        case pausable
        case cancelled
        case paused
        case kind
        static let all: [KeyPath] = [ .totalUnitCount, .completedUnitCount, .localizedDescription, .localizedAdditionalDescription, .cancellable, .pausable, .cancelled, .paused, .kind ]
    }
}

/// A progress object whose attributes reflect that of an external progress
/// tree.
private final class ProxyProgress: Progress {
    let original: Progress

    init(cloning original: Progress) {

    }

    func attach() {
        if Progress.current()?.isCancelled == true {
            original.cancel()
        }

        if Progress.current()?.isPaused == true {
            original.pause()
        }

        for keyPath in KVO.keyPaths {
            original.addObserver(self, forKeyPath: keyPath, options: [.initial, .new], context: &KVO.context)
        }
    }

    func detach() {
        for keyPath in KVO.keyPaths {
            original.removeObserver(self, forKeyPath: keyPath, context: &KVO.context)
        }
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        switch (keyPath, context) {
        case (KVO.cancelled?, (&KVO.context)?):
            guard change?[.newKey] as? Bool == true else { return }
            cancellationHandler = nil
            cancel()
        case (KVO.paused?, (&KVO.context)?):
            if change?[.newKey] as? Bool == true {
                pausingHandler = nil
                pause()
