private void enterSatisfyGuardAndLeaveInCurrentThread() {
   monitor.enter();
   try {
     guard.setSatisfied(true);
   } finally {
     monitor.leave();
   }
 }
 private void doWaitScenarioSetUp() {
   switch (scenario) {
     case SATISFIED_BEFORE_WAITING:
       guard.setSatisfied(true);
       break;
     case SATISFIED_WHILE_WAITING:
       guard.setSatisfied(false);
       enterSatisfyGuardAndLeaveInAnotherThread(); // enter blocks until we call waitFor
       break;
     case UNSATISFIED_BEFORE_AND_WHILE_WAITING:
       guard.setSatisfied(false);
       break;
     case SATISFIED_AND_INTERRUPTED_BEFORE_WAITING:
       guard.setSatisfied(true);
       Thread.currentThread().interrupt();
       break;
     case UNSATISFIED_AND_INTERRUPTED_BEFORE_WAITING:
       guard.setSatisfied(false);
       Thread.currentThread().interrupt();
       break;
     default:
       throw new AssertionError("unsupported scenario: " + scenario);
   }
 }
  private void runEnterTest() {
    assertFalse(Thread.currentThread().isInterrupted());
    assertFalse(monitor.isOccupiedByCurrentThread());

    doEnterScenarioSetUp();

    boolean interruptedBeforeCall = Thread.currentThread().isInterrupted();
    Outcome actualOutcome = doCall();
    boolean occupiedAfterCall = monitor.isOccupiedByCurrentThread();
    boolean interruptedAfterCall = Thread.currentThread().isInterrupted();

    if (occupiedAfterCall) {
      guard.setSatisfied(true);
      monitor.leave();
      assertFalse(monitor.isOccupiedByCurrentThread());
    }

    assertEquals(expectedOutcome, actualOutcome);
    assertEquals(expectedOutcome == Outcome.SUCCESS, occupiedAfterCall);
    assertEquals(
        interruptedBeforeCall && expectedOutcome != Outcome.INTERRUPT, interruptedAfterCall);
  }
  private void runWaitTest() {
    assertFalse(Thread.currentThread().isInterrupted());
    assertFalse(monitor.isOccupiedByCurrentThread());
    monitor.enter();
    try {
      assertTrue(monitor.isOccupiedByCurrentThread());

      doWaitScenarioSetUp();

      boolean interruptedBeforeCall = Thread.currentThread().isInterrupted();
      Outcome actualOutcome = doCall();
      boolean occupiedAfterCall = monitor.isOccupiedByCurrentThread();
      boolean interruptedAfterCall = Thread.currentThread().isInterrupted();

      assertEquals(expectedOutcome, actualOutcome);
      assertTrue(occupiedAfterCall);
      assertEquals(
          interruptedBeforeCall && expectedOutcome != Outcome.INTERRUPT, interruptedAfterCall);
    } finally {
      guard.setSatisfied(true);
      monitor.leave();
      assertFalse(monitor.isOccupiedByCurrentThread());
    }
  }
  @Override
  protected void tearDown() throws Exception {
    // We don't want to leave stray threads running after each test. At this point, every thread
    // launched by this test is either:
    //
    // (a) Blocked attempting to enter the monitor.
    // (b) Waiting for the single guard to become satisfied.
    // (c) Occupying the monitor and awaiting the tearDownLatch.
    //
    // Except for (c), every thread should occupy the monitor very briefly, and every thread leaves
    // the monitor with the guard satisfied. Therefore as soon as tearDownLatch is triggered, we
    // should be able to enter the monitor, and then we set the guard to satisfied for the benefit
    // of any remaining waiting threads.

    tearDownLatch.countDown();
    assertTrue(
        "Monitor still occupied in tearDown()",
        monitor.enter(UNEXPECTED_HANG_DELAY_MILLIS, TimeUnit.MILLISECONDS));
    try {
      guard.setSatisfied(true);
    } finally {
      monitor.leave();
    }
  }