             return // already finished
         }
         self.state = newState
+
         assert(handlers != nil)
         switch newState {
         case .pending: fatalError("Invalid transition")

    /// - parameter closure: The closure is called immediately on the current
    /// thread. You should start an asynchronous task and call either `succeed`
    /// or `fail` when it completes.
    public convenience init(_ closure: (_ succeed: @escaping (Value) -> Void, _ fail: @escaping (Error) -> Void) -> Void) {
        self.init(queue: .main, closure)
    }

    convenience init(queue: DispatchQueue, _ closure: (_ succeed: @escaping (Value) -> Void, _ fail: @escaping (Error) -> Void) -> Void) {
        self.init(queue: queue)
        closure({ self.succeed($0) }, { self.fail($0) }) // retain self
    }

    init(queue: DispatchQueue = .main) {

/// functions like `map`, `flatMap`, `zip`, `reduce` and more to compose futures.
///
/// By default, all of the callbacks and composing functions are executed on the
/// main queue (`DispatchQueue.main`). To change the queue use `observeOn` method.
public final class Future<Value, Error> {
    private var state: State = .pending
    private var handlers: Handlers? // nil when finished
