class AmbariAuthToLocalUserDetailsService implements UserDetailsService {

  @Override
  public UserDetails loadUserByUsername(String principal) throws UsernameNotFoundException {
    String username;

    // First see if there is a Kerberos-related authentication record for some user.
    Collection<UserAuthenticationEntity> entities = users.getUserAuthenticationEntities(UserAuthenticationType.KERBEROS, principal);

    // Zero or one value is expected.. if not, that is an issue.
    // If no entries are returned, we have not yet seen this principal.  If no, perform an auth-to-local translation
    // to determine what the local username is.
    if (CollectionUtils.isEmpty(entities)) {
      username = translatePrincipalName(principal);
      if (username == null) {
        String message = String.format("Failed to translate %s to a local username during Kerberos authentication.", principal);
        LOG.warn(message);
        throw new UsernameNotFoundException(message);
      }

      LOG.info("Translated {} to {} using auth-to-local rules during Kerberos authentication.", principal, username);
      return createUser(username, principal);
    } else if (entities.size() == 1) {
      UserEntity userEntity = entities.iterator().next().getUser();
      LOG.trace("Found KERBEROS authentication method for {} using principal {}", userEntity.getUserName(), principal);
      return createUserDetails(userEntity);
    } else {
      throw new AmbariAuthenticationException("", "Unexpected error due to collisions on the principal name", false);
    }
  }

    AmbariAuthToLocalUserDetailsService(Configuration configuration, Users users);

}