 //
 
 import Foundation
+
+/// Queue used to serialize updates to the binding notifications
+fileprivate let _bindingUpdateQueue = DispatchQueue(label: "io.logicalshift.bindingUpdate");
 
 ///
 /// Protocol implemented by objects that can be notified that they need to recalculate themselves

    }
    
    ///
    /// Check to see if all notifications are finished with and call doneObserving() if they are
    ///
    fileprivate func maybeDoneObserving() {
        // See if all the notifiers are finished with
        var allDone = true;
        for notifier in _actionsOnChanged {
            if notifier.target != nil {
                allDone = false;
                break;
            }
        }
        
        // Clear out eagerly if all notifiers are finished with
        if allDone {
            _actionsOnChanged = [];
            _isBound?.value = false;
            doneObserving();
        }
    }

    /// Calls a function any time this value is marked as changed
    ///
    public final func whenChangedNotify(_ target: Notifiable) -> Lifetime {
        // Record this action so we can re-run it when the value changes
        let wrapper = NotificationWrapper(target: target);
        let isFirstBinding: Bool = _bindingUpdateQueue.sync {
            _actionsOnChanged.append(wrapper);
            return _actionsOnChanged.count == 1;
        }
        
        // Perform actions if this is the first binding attached to this object
        if isFirstBinding {
            updateIsBound();
            beginObserving();
        }
        
        // Stop observing the action once the lifetime expires
        return CallbackLifetime(done: {
