@Transactional
  private List<UserGroup> getPrivilegesAndCreateGroups(
      LDAPUser user, boolean createNonExistingLdapGroup, User toSave) {
    GroupRepository groupRepo = ApplicationContextHolder.get().getBean(GroupRepository.class);

    List<UserGroup> ug = new LinkedList<UserGroup>();
    for (Map.Entry<String, Profile> privilege : user.getPrivileges().entries()) {
      // Add group privileges for each groups

      // Retrieve group id
      String groupName = privilege.getKey();
      Profile profile = privilege.getValue();

      Group group = groupRepo.findByName(groupName);

      if (group == null && createNonExistingLdapGroup) {
        group = new Group().setName(groupName);
        group = groupRepo.save(group);

        if (Log.isDebugEnabled(Geonet.LDAP)) {
          Log.debug(Geonet.LDAP, "  - Add LDAP group " + groupName + " for user.");
        }
      }
      if (group != null) {
        if (Log.isDebugEnabled(Geonet.LDAP)) {
          Log.debug(Geonet.LDAP, "  - Add LDAP group " + groupName + " for user.");
        }
        UserGroup usergroup = new UserGroup();
        usergroup.setGroup(group);
        usergroup.setUser(toSave);
        usergroup.setProfile(profile);
        ug.add(usergroup);
      } else {
        if (Log.isDebugEnabled(Geonet.LDAP)) {
          Log.debug(
              Geonet.LDAP,
              "  - Can't create LDAP group "
                  + groupName
                  + " for user. "
                  + "Group does not exist in local database or createNonExistingLdapGroup is set to false.");
        }
      }
    }
    return ug;
  }
  /**
   * Save or update an LDAP user to the local GeoNetwork database.
   *
   * @param user
   * @throws Exception
   */
  @Transactional
  public synchronized void saveUser(
      LDAPUser user, boolean importPrivilegesFromLdap, boolean createNonExistingLdapGroup)
      throws Exception {
    String userName = user.getUsername();
    if (Log.isDebugEnabled(Geonet.LDAP)) {
      Log.debug(Geonet.LDAP, "LDAP user sync for " + userName + " ...");
    }
    User toSave = getUser(user, importPrivilegesFromLdap, userName);

    // Add user groups
    if (importPrivilegesFromLdap) {
      entityManager.flush();
      entityManager.clear();
      List<UserGroup> ug = getPrivilegesAndCreateGroups(user, createNonExistingLdapGroup, toSave);
      entityManager.flush();
      setUserGroups(toSave, ug);
    }
  }
  @Transactional
  private User getUser(LDAPUser user, boolean importPrivilegesFromLdap, String userName) {
    UserRepository userRepo = ApplicationContextHolder.get().getBean(UserRepository.class);

    User loadedUser = userRepo.findOneByUsername(userName);
    User toSave;
    if (loadedUser != null) {
      // If we don't import privileges from LDAP
      // Set the LDAP user profile to be the one set
      // in the local database. If not, the db profile
      // would be always reset by merge.
      if (!importPrivilegesFromLdap) {
        user.getUser().setProfile(loadedUser.getProfile());
      }
      loadedUser.mergeUser(user.getUser(), false);
      if (Log.isDebugEnabled(Geonet.LDAP)) {
        Log.debug(
            Geonet.LDAP,
            "  - Update LDAP user "
                + user.getUsername()
                + " ("
                + loadedUser.getId()
                + ") in local database.");
      }
      toSave = loadedUser;

    } else {
      if (Log.isDebugEnabled(Geonet.LDAP)) {
        Log.debug(Geonet.LDAP, "  - Saving new LDAP user " + user.getUsername() + " to database.");
      }
      toSave = user.getUser();
    }
    toSave.getSecurity().setAuthType(LDAPConstants.LDAP_FLAG);
    toSave = userRepo.save(toSave);
    user.setUser(toSave);
    return toSave;
  }