@Override
    public Optional<Mail> tryTake(int priority) {
        checkIsMailboxThread();
        checkTakeStateConditions();
        Mail head = takeOrNull(batch, priority);
        if (head != null) {
            return Optional.of(head);
        }
        if (!hasNewMail) {
            return Optional.empty();
        }
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            final Mail value = takeOrNull(queue, priority);
            if (value == null) {
                return Optional.empty();
            }
            hasNewMail = !queue.isEmpty();
            return Optional.ofNullable(value);
        } finally {
            lock.unlock();
        }
    }
@Test
    void testConcurrentPutTakeNonBlockingAndWait() throws Exception {
        testPutTake(
                (mailbox -> {
                    Optional<Mail> optionalMail = mailbox.tryTake(DEFAULT_PRIORITY);
                    while (!optionalMail.isPresent()) {
                        optionalMail = mailbox.tryTake(DEFAULT_PRIORITY);
                    }
                    return optionalMail.get();
                }));
    }