import java.util.HashSet;


public class BiasableSet<E> {
  private final HashSet<E> set = new HashSet<>();
  private Thread biasThread;
  
  public void add(E element) throws InterruptedException {
    synchronized(set) {
      while (biasThread != null && Thread.currentThread() != biasThread) {
        set.wait();
      }
      set.add(element);  
    }
  }
  
  public void remove(Object element) throws InterruptedException {
    synchronized(set) {
      while (biasThread != null && Thread.currentThread() != biasThread) {
        set.wait();
      }
      set.remove(element);
    }
  }
  
  public boolean contains(Object element) {
    synchronized(set) {
      return set.contains(element);
    }
  }
  
  public void takeBias() {
    synchronized(set) {
      if (biasThread != null) {
        throw new IllegalStateException();
      }
      biasThread = Thread.currentThread();
    }
  }
  
  public void revokeBias() {
    synchronized(set) {
      if (biasThread != Thread.currentThread()) {
        throw new IllegalStateException();
      }
      biasThread = null;
      set.notifyAll();
    }
  }
}
 
