// Path: core/src/main/java/org/codeandmagic/promise/Either.java
// public static final class Left<T1, T2> extends Either<T1, T2> {
// 
//     private final T1 left;
// 
//     public Left(T1 left) {
//         this.left = left;
//     }
// 
//     @Override
//     public boolean isLeft() {
//         return true;
//     }
// 
//     @Override
//     public T1 getLeft() {
//         return left;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Left left1 = (Left) o;
// 
//         if (left != null ? !left.equals(left1.left) : left1.left != null) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         return left != null ? left.hashCode() : 0;
//     }
// }
// 
// Path: core/src/main/java/org/codeandmagic/promise/Either.java
// public static final class Right<T1, T2> extends Either<T1, T2> {
// 
//     private final T2 right;
// 
//     public Right(T2 right) {
//         this.right = right;
//     }
// 
//     @Override
//     public boolean isRight() {
//         return true;
//     }
// 
//     @Override
//     public T2 getRight() {
//         return right;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Right right1 = (Right) o;
// 
//         if (right != null ? !right.equals(right1.right) : right1.right != null) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         return right != null ? right.hashCode() : 0;
//     }
// }


import android.os.Handler;
import android.os.Looper;
import org.codeandmagic.promise.*;
import org.codeandmagic.promise.Either.Left;
import org.codeandmagic.promise.Either.Right;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
        triggerCompleted();
        for (final Callback<Success> s : mSuccessCallbacks) {
            s.onCallback(mResult);
        }
    }

    protected void failure(final Failure failure) {
        if (mState == State.PENDING) {
            this.mFailure = failure;
            this.mState = State.FAILED;
            triggerFailure();
        } else {
            throw new IllegalStateException("Can't fail a Promise3 which is in mState '" + mState.name() + "'.");
        }
    }

    protected final void triggerFailure() {
        triggerCompleted();
        for (final Callback<Failure> f : mFailureCallbacks) {
            f.onCallback(mFailure);
        }
    }

    protected final void complete(Either<Failure, Success> either) {
        if (either.isLeft()) failure(either.getLeft());
        else success(either.getRight());
    }

    protected final void triggerCompleted() {
        for (final Callback<Either<Failure, Success>> c : mCompleteCallbacks) {
// Path: core/src/main/java/org/codeandmagic/promise/Either.java
// public static final class Left<T1, T2> extends Either<T1, T2> {
// 
//     private final T1 left;
// 
//     public Left(T1 left) {
//         this.left = left;
//     }
// 
//     @Override
//     public boolean isLeft() {
//         return true;
//     }
// 
//     @Override
//     public T1 getLeft() {
//         return left;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Left left1 = (Left) o;
// 
//         if (left != null ? !left.equals(left1.left) : left1.left != null) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         return left != null ? left.hashCode() : 0;
//     }
// }
// 
// Path: core/src/main/java/org/codeandmagic/promise/Either.java
// public static final class Right<T1, T2> extends Either<T1, T2> {
// 
//     private final T2 right;
// 
//     public Right(T2 right) {
//         this.right = right;
//     }
// 
//     @Override
//     public boolean isRight() {
//         return true;
//     }
// 
//     @Override
//     public T2 getRight() {
//         return right;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Right right1 = (Right) o;
// 
//         if (right != null ? !right.equals(right1.right) : right1.right != null) return false;
// 
//         return true;
//     }
// 
//     @Override
//     public int hashCode() {
//         return right != null ? right.hashCode() : 0;
//     }
// }


// Path: core/src/main/java/org/codeandmagic/promise/impl/AbstractPromise3.java
import android.os.Handler;
import android.os.Looper;
import org.codeandmagic.promise.*;
import org.codeandmagic.promise.Either.Left;
import org.codeandmagic.promise.Either.Right;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

        triggerCompleted();
        for (final Callback<Success> s : mSuccessCallbacks) {
            s.onCallback(mResult);
        }
    }

    protected void failure(final Failure failure) {
        if (mState == State.PENDING) {
            this.mFailure = failure;
            this.mState = State.FAILED;
            triggerFailure();
        } else {
            throw new IllegalStateException("Can't fail a Promise3 which is in mState '" + mState.name() + "'.");
        }
    }

    protected final void triggerFailure() {
        triggerCompleted();
        for (final Callback<Failure> f : mFailureCallbacks) {
            f.onCallback(mFailure);
        }
    }

    protected final void complete(Either<Failure, Success> either) {
        if (either.isLeft()) failure(either.getLeft());
        else success(either.getRight());
    }

    protected final void triggerCompleted() {
        for (final Callback<Either<Failure, Success>> c : mCompleteCallbacks) {
            c.onCallback(isSuccess() ? new Right<Failure, Success>(mResult) : new Left<Failure, Success>(mFailure));