class RunStateRecordedFutureTask<V> extends FutureTask<V> {
    private AtomicBoolean hasRun = new AtomicBoolean();

    public RunStateRecordedFutureTask(Callable<V> callable) {
        super(callable);
    }

    @Override
    public void run() {
        this.hasRun.set(true);
        super.run();
    }

    public V getAfterRun() throws InterruptedException, ExecutionException,
                          FutureTaskNotRunYetException, FutureTaskNotCompleted {<FILL_FUNCTION_BODY>}
}

        if (!hasRun.get()) {
            throw new FutureTaskNotRunYetException();
        }

        if (!isDone()) {
            throw new FutureTaskNotCompleted();
        }

        return super.get();
    
<methods>public void <init>(Callable<V>) ,public void <init>(java.lang.Runnable, V) ,public boolean cancel(boolean) ,public V get() throws java.lang.InterruptedException, java.util.concurrent.ExecutionException,public V get(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException, java.util.concurrent.TimeoutException,public boolean isCancelled() ,public boolean isDone() ,public void run() ,public java.lang.String toString() <variables>private static final int CANCELLED,private static final int COMPLETING,private static final int EXCEPTIONAL,private static final int INTERRUPTED,private static final int INTERRUPTING,private static final int NEW,private static final int NORMAL,private static final java.lang.invoke.VarHandle RUNNER,private static final java.lang.invoke.VarHandle STATE,private static final java.lang.invoke.VarHandle WAITERS,private Callable<V> callable,private java.lang.Object outcome,private volatile java.lang.Thread runner,private volatile int state,private volatile java.util.concurrent.FutureTask.WaitNode waiters