@Override
  public Optional<AuthenticatedDevice> authenticate(BasicCredentials basicCredentials) {
    boolean succeeded = false;
    String failureReason = null;

    try {
      final UUID accountUuid;
      final byte deviceId;
      {
        final Pair<String, Byte> identifierAndDeviceId = getIdentifierAndDeviceId(basicCredentials.getUsername());

        accountUuid = UUID.fromString(identifierAndDeviceId.first());
        deviceId = identifierAndDeviceId.second();
      }

      Optional<Account> account = accountsManager.getByAccountIdentifier(accountUuid);

      if (account.isEmpty()) {
        failureReason = "noSuchAccount";
        return Optional.empty();
      }

      Optional<Device> device = account.get().getDevice(deviceId);

      if (device.isEmpty()) {
        failureReason = "noSuchDevice";
        return Optional.empty();
      }

      SaltedTokenHash deviceSaltedTokenHash = device.get().getAuthTokenHash();
      if (deviceSaltedTokenHash.verify(basicCredentials.getPassword())) {
        succeeded = true;
        Account authenticatedAccount = updateLastSeen(account.get(), device.get());
        if (deviceSaltedTokenHash.getVersion() != SaltedTokenHash.CURRENT_VERSION) {
          OLD_TOKEN_VERSION_COUNTER.increment();
          authenticatedAccount = accountsManager.updateDeviceAuthentication(
              authenticatedAccount,
              device.get(),
              SaltedTokenHash.generateFor(basicCredentials.getPassword()));  // new credentials have current version
        }
        return Optional.of(new AuthenticatedDevice(authenticatedAccount, device.get()));
      } else {
        failureReason = "incorrectPassword";
        return Optional.empty();
      }
    } catch (IllegalArgumentException | InvalidAuthorizationHeaderException iae) {
      failureReason = "invalidHeader";
      return Optional.empty();
    } finally {
      Tags tags = Tags.of(
          AUTHENTICATION_SUCCEEDED_TAG_NAME, String.valueOf(succeeded));

      if (StringUtils.isNotBlank(failureReason)) {
        tags = tags.and(AUTHENTICATION_FAILURE_REASON_TAG_NAME, failureReason);
      }

      Metrics.counter(AUTHENTICATION_COUNTER_NAME, tags).increment();
    }
  }
@Test
  void testAuthenticateAccountNotFound() {
    assertThat(accountAuthenticator.authenticate(new BasicCredentials(UUID.randomUUID().toString(), "password")))
        .isEmpty();
  }