         queue.setSpecific(key: _contextSpecificName, value: storage);
         
         return queue;
+    }
+    
+    ///
+    /// Retrieves a context queue, or waits for one to become available
+    ///
+    static func retrieveContextQueue() -> DispatchQueue {
+        // Acquire the semaphore
+        _queueSemaphore.wait();
+        defer { _queueSemaphore.signal(); }
+        
+        // If there are no queues available, then wait for someone to signal the wait semaphore
+        while _contextQueues.count <= 0 {
+            // Release the queue semaphore so that queues can be returned
+            _queueSemaphore.signal();
+            
+            // Wait for the wait semaphore to be signaled (indicates a queue was returned to the pool)
+            _queueWaitSemaphore.wait();
+            _queueWaitSemaphore.signal();
+            
+            // Re-acquire the queue semaphore so we can check for queues
+            _queueSemaphore.wait();
+        }
+        
+        // If we got the semaphore, there is always at least one queue available in the list
+        let queue = _contextQueues.popLast()!;
+        
+        // If we just got the last queue, then acquire the wait semaphore so we can block anything waiting for a queue
+        if _contextQueues.count == 0 {
+            _queueWaitSemaphore.wait();
+        }
+        
+        // Release the semaphore and return the result
+        return queue;
+    }
+    
+    ///
+    /// Returns a context queue to the pool
+    ///
+    static func returnContextQueue(_ queue: DispatchQueue) {
+        // Acquire the semaphore
+        _queueSemaphore.wait();
+        defer { _queueSemaphore.signal(); }
+        
+        // If this is the first queue back in the pool, then wake any threads waiting for more queues
+        if _contextQueues.count == 0 {
+            _queueWaitSemaphore.signal();
+        }
+        
+        // Return queue to the pool
+        _contextQueues.append(queue);
+    }
+}
+
+///
+/// The binding context is used to keep track of what bindings are being accessed
+///
+public class BindingContext {
+    ///
+    /// The dependencies that have been created in this context
+    ///
+    fileprivate var _dependencies = CombinedChangeable();
+    
+    ///
+    /// Dependencies that we expected to see
+    ///
+    fileprivate var _expectedDependencies: CombinedChangeable?;
+    
+    ///
+    /// Call BindingContext.current to get the binding context for the current queue
+    ///
+    fileprivate init() {
+    }
+    
+    fileprivate static var currentStorage: QueueBindingContext? {
+        @inline(__always)
+        get {
+            // Get the context pointer from the queue
+            return DispatchQueue.getSpecific(key: _contextSpecificName);
+        }
+    }
+    
+    ///
+    /// Retrieves the binding context for the current queue (or nil if there isn't one)
+    ///
+    public static var current: BindingContext? {
+        get {
+            return currentStorage?.context;
+        }
     }
     
     ///

            action();
            existingStorage.context = oldContext;
        } else {
            // Current queue doesn't have any context stored, move on to the default queue
            // Could also call createQueueWithNewContext() here, but that is slow
            _defaultContextQueue.sync(execute: {
                let existingStorage = BindingContext.currentStorage!;
                
                // Generate a new context

}

///
/// Retrieves/returns binding context queues
///
private class BindingQueuePool {
    ///
    /// Creates a set of context queues
    ///
    static func createContextQueues(_ count: Int) -> [DispatchQueue] {
        var result = [DispatchQueue]();
        
        for _ in 0..<count {
            let queue = BindingQueuePool.createQueueWithNewContext();
            result.append(queue);
        }
        
        return result;
    }
    
    ///
    /// Creates a new dispatch queue with a new binding context
    ///
    static func createQueueWithNewContext() -> DispatchQueue {
        // Generate a new context
        let newContext  = BindingContext();
        
