@Override
    public Optional<P> authenticate(C credentials) throws AuthenticationException {
        try (Timer.Context context = gets.time()) {
            return cache.get(credentials);
        } catch (CompletionException e) {
            final Throwable cause = e.getCause();
            if (cause instanceof InvalidCredentialsException) {
                return Optional.empty();
            }
            if (cause instanceof AuthenticationException) {
                throw (AuthenticationException) cause;
            }
            if (cause == null) {
                throw new AuthenticationException(e);
            }
            throw new AuthenticationException(cause);
        }
    }
@Test
    void cachesTheFirstReturnedPrincipal() throws Exception {
        assertThat(cached.authenticate("credentials")).isEqualTo(Optional.<Principal>of(new PrincipalImpl("principal")));
        assertThat(cached.authenticate("credentials")).isEqualTo(Optional.<Principal>of(new PrincipalImpl("principal")));

        verify(underlying, times(1)).authenticate("credentials");
    }