docs: @CanIgnoreReturnValue
    @Override
    public V get(long timeout, TimeUnit unit)
        throws InterruptedException, TimeoutException, ExecutionException {
      // NOTE: if timeout < 0, remainingNanos will be < 0 and we will fall into the while(true) loop
      // at the bottom and throw a timeoutexception.
      long remainingNanos = unit.toNanos(timeout); // we rely on the implicit null check on unit.
      if (Thread.interrupted()) {
        throw new InterruptedException();
      }
      Object localValue = value;
      if (localValue != null & !(localValue instanceof AbstractFuture.SetFuture)) {
        return getDoneValue(localValue);
      }
      // we delay calling nanoTime until we know we will need to either park or spin
      final long endNanos = remainingNanos > 0 ? System.nanoTime() + remainingNanos : 0;
      long_wait_loop:
      if (remainingNanos >= SPIN_THRESHOLD_NANOS) {
        Waiter oldHead = waiters;
        if (oldHead != Waiter.TOMBSTONE) {
          Waiter node = new Waiter();
          do {
            node.setNext(oldHead);
            if (ATOMIC_HELPER.casWaiters(this, oldHead, node)) {
              while (true) {
                LockSupport.parkNanos(this, remainingNanos);
                // Check interruption first, if we woke up due to interruption we need to honor that.
                if (Thread.interrupted()) {
                  removeWaiter(node);
                  throw new InterruptedException();
                }
  
                // Otherwise re-read and check doneness. If we loop then it must have been a spurious
                // wakeup
                localValue = value;
                if (localValue != null & !(localValue instanceof AbstractFuture.SetFuture)) {
                  return getDoneValue(localValue);
                }
  
                // timed out?
                remainingNanos = endNanos - System.nanoTime();
                if (remainingNanos < SPIN_THRESHOLD_NANOS) {
                  // Remove the waiter, one way or another we are done parking this thread.
                  removeWaiter(node);
                  break long_wait_loop; // jump down to the busy wait loop
                }
              }
            }
            oldHead = waiters; // re-read and loop.
          } while (oldHead != Waiter.TOMBSTONE);
        }
        // re-read value, if we get here then we must have observed a TOMBSTONE while trying to add a
        // waiter.
        return getDoneValue(value);
      }
      // If we get here then we have remainingNanos < SPIN_THRESHOLD_NANOS and there is no node on the
      // waiters list
      while (remainingNanos > 0) {
        localValue = value;
        if (localValue != null & !(localValue instanceof AbstractFuture.SetFuture)) {
          return getDoneValue(localValue);
        }
        if (Thread.interrupted()) {
          throw new InterruptedException();
        }
        remainingNanos = endNanos - System.nanoTime();
      }
      throw new TimeoutException();
    }