package com.intellij.util.concurrency;

import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import org.jetbrains.annotations.Nullable;

import java.util.concurrent.*;
import java.util.concurrent.Semaphore;

public class FutureResult<T> implements Future<T> {
  private final Semaphore mySema = new Semaphore(0);
  private volatile Ref<Pair<Object, Boolean>> myValue;

  public void reset() {
    mySema.drainPermits();
    myValue = null;
  }

  public boolean cancel(boolean mayInterruptIfRunning) {
    return false;
  }

  public boolean isCancelled() {
    return false;
  }

  public boolean isDone() {
    return myValue != null;
  }

  public void set(@Nullable T result) {
    assert myValue == null;

    myValue = Ref.create(Pair.create((Object)result, true));
    mySema.release();
  }

  public void setException(Throwable e) {
    assert myValue == null;

    myValue = Ref.create(Pair.create((Object)e, false));
    mySema.release();
  }

  public T get() throws InterruptedException, ExecutionException {
    mySema.acquire();
    try {
      return doGet();
    }
    finally {
      mySema.release();
    }
  }

  public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    if (!mySema.tryAcquire(timeout, unit)) throw new TimeoutException();
    try {
      return doGet();
    }
    finally {
      mySema.release();
    }
  }

  private T doGet() throws ExecutionException {
    Pair<Object, Boolean> pair = myValue.get();
    if (!pair.second) throw new ExecutionException(((Throwable)pair.first).getMessage(), (Throwable)pair.first);
    return (T)pair.first;
  }
}

@@ -699,39 +699,36 @@
 sult) %7B%0A    
-assert 
+if (
 myValue 
 == null;%0A%0A  
@@ -707,39 +707,97 @@
     if (myValue 
-=
+!
 = null
+) throw new IllegalStateException(%22Result is already set%22)
 ;%0A%0A    myValue =

correct debug process startup sequence(prevent mem leaks on error)