/**
   * Creates a {@link User} object containing the information in the {@link Attributes} object.
   *
   * @param directoryAttributes The directory-specific {Attributes} object to take the values from
   * @return A populated {User} object.
   */
  public UserTemplateWithAttributes mapUserFromAttributes(Attributes directoryAttributes)
      throws NamingException {
    if (directoryAttributes == null) {
      throw new UncategorizedLdapException("Cannot map from null attributes");
    }

    String username = getUsernameFromAttributes(directoryAttributes);

    UserTemplate user = new UserTemplate(username, directoryId);

    // active
    user.setActive(getUserActiveFromAttribute(directoryAttributes));

    // email address
    user.setEmailAddress(StringUtils.defaultString(getUserEmailFromAttribute(directoryAttributes)));

    // first (given) name
    user.setFirstName(getUserFirstNameFromAttribute(directoryAttributes));

    // surname
    user.setLastName(getUserLastNameFromAttribute(directoryAttributes));

    // display name
    user.setDisplayName(getUserDisplayNameFromAttribute(directoryAttributes));

    // pre-populate user names (first name, last name, display name may need to be constructed)
    User prepopulatedUser = UserUtils.populateNames(user);

    return UserTemplateWithAttributes.ofUserWithNoAttributes(prepopulatedUser);
  }
  /**
   * Creates an LDAP {@link Attributes} object containing the information in the {@link User}
   * object.
   *
   * @param user The object to take the values from
   * @return A populated directory-specific Attributes object.
   */
  public Attributes mapAttributesFromUser(User user) throws NamingException {
    if (user == null) {
      throw new UncategorizedLdapException("Cannot map attributes from a null User");
    }

    // pre-populate user names (first name, last name, display name may need to be constructed)
    User populatedUser = UserUtils.populateNames(user);

    Attributes directoryAttributes = new BasicAttributes(true);

    directoryAttributes.put(
        new BasicAttribute(
            ldapPropertiesMapper.getObjectClassAttribute(),
            ldapPropertiesMapper.getUserObjectClass()));

    // username
    putValueInAttributes(
        populatedUser.getName(), ldapPropertiesMapper.getUserNameAttribute(), directoryAttributes);

    // email address
    putValueInAttributes(
        populatedUser.getEmailAddress(),
        ldapPropertiesMapper.getUserEmailAttribute(),
        directoryAttributes);

    // first (given) name
    putValueInAttributes(
        populatedUser.getFirstName(),
        ldapPropertiesMapper.getUserFirstNameAttribute(),
        directoryAttributes);

    // surname
    putValueInAttributes(
        populatedUser.getLastName(),
        ldapPropertiesMapper.getUserLastNameAttribute(),
        directoryAttributes);

    // full name
    putValueInAttributes(
        populatedUser.getDisplayName(),
        ldapPropertiesMapper.getUserDisplayNameAttribute(),
        directoryAttributes);

    // TODO: currently we don't support arbitrary attributes / iconLocation / active

    return directoryAttributes;
  }