             future.fail(error)
         }
     }
-
-    // MARK: Scheduler
 
     public enum Scheduler {
         /// Runs immediately if on the main thread, otherwise asynchronously on the main thread.

        }
    }

    // MARK: Private

    private struct Handlers {
        var success = [(Value) -> Void]()
        var failure = [(Error) -> Void]()
    }
}

extension Future {
    // MARK: Map

    /// Returns a future with the result of mapping the given closure over the
    /// current future's value.
    public func map<NewValue>(_ transform: @escaping (Value) -> NewValue) -> Future<NewValue, Error> {
        let future = Future<NewValue, Error>()
        cascade(future, success: { future.succeed(transform($0)) })
        return future
    }

    /// Returns a future which is eventually resolved with the result of the
    /// future returned by the `transform` closure. The `transform` closure is
    /// called when the current future receives a value.
    ///
    /// Allows you to "chain" multiple async operations:
    ///
    /// ```
    /// let avatar = user
    ///     .map { $0.avatarURL }
    ///     .flatMap(loadAvatar)
    ///
    /// // user: Future<User, Error>
    /// // func loadAvatar(url: URL) -> Future<Avatar, Error>
    /// ```
    public func flatMap<NewValue>(_ transform: @escaping (Value) -> Future<NewValue, Error>) -> Future<NewValue, Error> {
        let future = Future<NewValue, Error>()
        cascade(future, success: { transform($0).cascade(future) })
        return future
    }

    /// Returns a future with the error which is the result of mapping the given
    /// closure over the current future's error.
    public func mapError<NewError>(_ transform: @escaping (Error) -> NewError) -> Future<Value, NewError> {
        let future = Future<Value, NewError>()
        cascade(future, failure: { future.fail(transform($0)) })
        return future
    }

    /// Returns a future which is eventually resolved with the result of the
    /// future returned by the `transform` closure. The `transform` closure is
    /// called when the current future receives an error.
    ///
    /// Allows you to continue the chain of futures by "recovering" from an error
    /// with a new future.
    public func flatMapError<NewError>(_ transform: @escaping (Error) -> Future<Value, NewError>) -> Future<Value, NewError> {
        let future = Future<Value, NewError>()
        cascade(future, failure: { transform($0).cascade(future) })
        return future
    }

    // MARK: Zip

    /// Returns a future which succeedes when all the given futures succeed. If
    /// any of the futures fail, the returned future also fails with that error.
    public static func zip<V2>(_ f1: Future<Value, Error>, _ f2: Future<V2, Error>) -> Future<(Value, V2), Error> {
        let future = Future<(Value, V2), Error>()
        func success(value: Any) {
            guard let v1 = f1.value, let v2 = f2.value else { return }
            future.succeed((v1, v2))
        }
        f1.cascade(future, success: success)
        f2.cascade(future, success: success)
        return future
    }

    /// Returns a future which succeedes when all the given futures succeed. If
    /// any of the futures fail, the returned future also fails with that error.
    public static func zip<V2, V3>(_ f1: Future<Value, Error>, _ f2: Future<V2, Error>, _ f3: Future<V3, Error>) -> Future<(Value, V2, V3), Error> {
        return Future.zip(f1, Future<V2, Error>.zip(f2, f3)).map { value in
            return (value.0, value.1.0, value.1.1)
        }
    }

    /// Returns a future which succeedes when all the given futures succeed. If
    /// any of the futures fail, the returned future also fails with that error.
    public static func zip(_ futures: [Future<Value, Error>]) -> Future<[Value], Error> {
        return Future<[Value], Error>.reduce([], futures) { result, value in
            result + [value]
        }
    }

    // MARK: Reduce

    /// Returns a future that succeeded when all the given futures succeed.
    /// The future contains the result of combining the `initialResult` with
    /// the values of all the given future. If any of the futures fail, the
    /// returned future also fails with that error.
    public static func reduce<V2>(_ initialResult: Value, _ futures: [Future<V2, Error>], _ combiningFunction: @escaping (Value, V2) -> Value) -> Future<Value, Error> {
        return futures.reduce(Future(value: initialResult)) { lhs, rhs in
            return Future.zip(lhs, rhs).map(combiningFunction)
        }
    }
}

// Using the same lock across instances is safe because Future doesn't invoke
// any client code inside it.

        semaphore.wait()
        return result! // Must have result at this point
    }
}

// MARK: - Result, Scheduler, Promise

extension Future {

    public enum Result {
        case success(Value), failure(Error)
