/**
   * This is the main method of this class, calling authentication, authorization and user details
   * mapping.
   *
   * @param authentication object to populate
   * @return Populated authentication object
   * @throws AuthenticationException
   */
  public Authentication authenticate(final Authentication authentication)
      throws AuthenticationException {
    Assert.isInstanceOf(
        UsernamePasswordAuthenticationToken.class,
        authentication,
        messages.getMessage(
            "AbstractUserDetailsAuthenticationProvider.onlySupports",
            "Only UsernamePasswordAuthenticationToken is supported"));

    logger.finest("CustomLdapAuthenticationProvider: authenticate");

    final UsernamePasswordAuthenticationToken userToken =
        (UsernamePasswordAuthenticationToken) authentication;

    String username = userToken.getName();
    String password = (String) authentication.getCredentials();

    logger.fine("Processing authentication request for user: "******"LdapAuthenticationProvider.emptyUsername", "Empty Username"));
    }

    Assert.notNull(password, "Null password was supplied in authentication token");

    try {
      DirContextOperations userData = getAuthenticator().authenticate(authentication);

      Collection<GrantedAuthority> extraAuthorities =
          loadUserAuthorities(userData, username, password);

      Collection<String> userAuthGroups = loadUserAuthGroups(userData, username, password);

      ExtendedLdapUserDetailsImpl extendedUserDetails =
          userDetailsContextMapper.mapUserFromContext(
              userData, username, extraAuthorities, userAuthGroups);

      return createSuccessfulAuthentication(userToken, extendedUserDetails);

    } catch (PasswordPolicyException ppe) {
      // The only reason a ppolicy exception can occur during a bind is that the account is locked.
      throw new LockedException(
          messages.getMessage(ppe.getStatus().getErrorCode(), ppe.getStatus().getDefaultMessage()));
    } catch (UsernameNotFoundException notFound) {
      if (hideUserNotFoundExceptions) {
        throw new BadCredentialsException(
            messages.getMessage("LdapAuthenticationProvider.badCredentials", "Bad credentials"));
      } else {
        throw notFound;
      }
    } catch (NamingException ldapAccessFailure) {
      throw new AuthenticationServiceException(ldapAccessFailure.getMessage(), ldapAccessFailure);
    }
  }
 @Override
 protected DirContextOperations doAuthentication(
     UsernamePasswordAuthenticationToken authentication) {
   try {
     return getAuthenticator().authenticate(authentication);
   } catch (PasswordPolicyException ppe) {
     // The only reason a ppolicy exception can occur during a bind is that the
     // account is locked.
     throw new LockedException(
         this.messages.getMessage(
             ppe.getStatus().getErrorCode(), ppe.getStatus().getDefaultMessage()));
   } catch (UsernameNotFoundException notFound) {
     if (this.hideUserNotFoundExceptions) {
       throw new BadCredentialsException(
           this.messages.getMessage(
               "LdapAuthenticationProvider.badCredentials", "Bad credentials"));
     } else {
       throw notFound;
     }
   } catch (NamingException ldapAccessFailure) {
     throw new InternalAuthenticationServiceException(
         ldapAccessFailure.getMessage(), ldapAccessFailure);
   }
 }