     
     
     /// duplicate the setting with name
-    func duplicateSetting(name: String) throws {
+    final func duplicateSetting(name: String) throws {
         
         let newName = self.savableSettingName(for: name, appendCopySuffix: true)
         

    
    
    /// return a setting file URL in the user's Application Support domain (don't care if it exists)
    func preparedURLForUserSetting(name: String) -> URL {
        
        return self.userSettingDirectoryURL.appendingPathComponent(name).appendingPathExtension(self.filePathExtension)
    }
    
    
    /// whether the setting name is one of the bundled settings
    func isBundledSetting(name: String) -> Bool {
        
        return self.bundledSettingNames.contains(name)
    }
    
    
    /// whether the setting name is one of the bundled settings that is customized by user
    func isCustomizedBundledSetting(name: String) -> Bool {
        
        return self.isBundledSetting(name: name) && (self.urlForUserSetting(name: name) != nil)
    }
    
    
    /// return setting name appending number suffix without extension
    func savableSettingName(for proposedName: String, appendCopySuffix: Bool = false) -> String {
        
        let suffix = appendCopySuffix ? NSLocalizedString("copy", comment: "copied file suffix") : nil
        

    
    
    /// update internal cache data
    final func updateCache(completionHandler: @escaping (() -> Void) = {}) {
        
        DispatchQueue.global().async { [weak self, previousSettingNames = self.settingNames] in
            self?.loadUserSettings()
            
            let didUpdateList = self?.settingNames != previousSettingNames
            
            DispatchQueue.main.sync {
                if didUpdateList {
                    self?.notifySettingListUpdate()
                }
                
                completionHandler()
            }
        }
    }
    
    
    /// notify about a line-up update of managed setting files.
    final func notifySettingListUpdate() {
        
        NotificationCenter.default.post(name: SettingFileManager.didUpdateSettingListNotification, object: self)
    }
    
    
    /// notify about change of a managed setting
    final func notifySettingUpdate(oldName: String, newName: String) {
        
        NotificationCenter.default.post(name: SettingFileManager.didUpdateSettingNotification, object: self,
                                        userInfo: [SettingFileManager.NotificationKey.old: oldName,
