 
 public class Future<T>: Hashable {
     fileprivate var value: FutureValue<T> = .incomplete
+    fileprivate let _fullfilled = Atomic<Bool>(value: false)
     fileprivate let checkForPossibleDeadlock: Bool
     public let eventLoop: EventLoop
     
+    public var fulfilled: Bool {
+        return _fullfilled.load()
+    }
+
     public var result: T? {
         get {
             switch value {

    /// A Future<T> that has already failed
    init(eventLoop: EventLoop, checkForPossibleDeadlock: Bool, error: Error) {
        self.value = .failure(error)
        self.futureLock = ConditionLock(value: 1)
        self.eventLoop = eventLoop
        self.checkForPossibleDeadlock = checkForPossibleDeadlock
    }

    public func thenIfError(callback: @escaping (Error) throws -> T) -> Future<T> {
        return thenIfError { return Future<T>(eventLoop: self.eventLoop, checkForPossibleDeadlock: self.checkForPossibleDeadlock, result: try callback($0)) }
    }

    
    /// Add a callback.  If there's already a value, invoke it and return the resulting list of new callback functions.
    fileprivate func _addCallback(callback: @escaping () -> CallbackList) -> CallbackList {
        assert(eventLoop.inEventLoop)
        switch value {
        case .incomplete:
            callbacks.append(callback: callback)
            return CallbackList()
        default:
            return callback()
        }
    }
    
    /// Add a callback.  If there's already a value, run as much of the chain as we can.
    fileprivate func _whenComplete(callback: @escaping () -> CallbackList) {
        if eventLoop.inEventLoop {
            _addCallback(callback: callback)._run()
        } else {
            eventLoop.execute {
                self._addCallback(callback: callback)._run()
            }
        }
    }
