/**
   * Until {@link #condition()} becomes <code>true</code> or the timeout elapses, call {@link
   * Display#sleep()} and run the event loop.
   *
   * <p>If <code>timeout &lt; 0</code>, the event loop is never driven and only the condition is
   * checked. If <code>timeout == 0</code>, the event loop is driven at most once, but <code>
   * Display.sleep()</code> is never invoked.
   *
   * @param display the display to run the event loop of
   * @param timeout the timeout in milliseconds
   * @return <code>true</code> if the condition became <code>true</code>, <code>false</code> if the
   *     timeout elapsed
   */
  public final boolean waitForCondition(Display display, long timeout) {
    // if the condition already holds, succeed
    if (condition()) return true;

    if (timeout < 0) return false;

    // if driving the event loop once makes the condition hold, succeed
    // without spawning a thread.
    driveEventQueue(display);
    if (condition()) return true;

    // if the timeout is negative or zero, fail
    if (timeout == 0) return false;

    // repeatedly sleep until condition becomes true or timeout elapses
    DisplayWaiter waiter = new DisplayWaiter(display);
    DisplayWaiter.Timeout timeoutState = waiter.start(timeout);
    boolean condition;
    try {
      do {
        if (display.sleep()) driveEventQueue(display);
        condition = condition();
      } while (!condition && !timeoutState.hasTimedOut());
    } finally {
      waiter.stop();
    }
    return condition;
  }
  /**
   * Call {@link Display#sleep()} and run the event loop once if <code>sleep</code> returns before
   * the timeout elapses. Returns <code>true</code> if any events were processed, <code>false</code>
   * if not.
   *
   * <p>If <code>timeout &lt; 0</code>, nothing happens and false is returned. If <code>timeout == 0
   * </code>, the event loop is driven exactly once, but <code>Display.sleep()</code> is never
   * invoked.
   *
   * @param display the display to run the event loop of
   * @param timeout the timeout in milliseconds
   * @return <code>true</code> if any event was taken off the event queue, <code>false</code> if not
   */
  public static boolean runEventLoop(Display display, long timeout) {
    if (timeout < 0) return false;

    if (timeout == 0) return driveEventQueue(display);

    // repeatedly sleep until condition becomes true or timeout elapses
    DisplayWaiter waiter = new DisplayWaiter(display);
    DisplayWaiter.Timeout timeoutState = waiter.start(timeout);
    boolean events = false;
    if (display.sleep() && !timeoutState.hasTimedOut()) {
      driveEventQueue(display);
      events = true;
    }
    waiter.stop();
    return events;
  }