/**
   * Delete the group with the given Id The delete is apply recursively to the sub-groups
   *
   * @param ddManager
   * @param group
   * @param onlyInSilverpeas
   * @return
   * @throws AdminException
   */
  public String deleteGroupById(
      DomainDriverManager ddManager, Group group, boolean onlyInSilverpeas) throws AdminException {
    try {
      ddManager.getOrganizationSchema();
      if (group.getDomainId() != null && !onlyInSilverpeas) {
        ddManager.deleteGroup(group.getId());
      }
      // Delete the group node from Silverpeas
      ddManager.getOrganization().group.removeGroup(idAsInt(group.getId()));

      // Delete index of group information
      ddManager.unindexGroup(group.getId());

      return group.getId();
    } catch (Exception e) {
      SynchroReport.error(
          "GroupManager.deleteGroupById()",
          "problème lors de la suppression du groupe " + group.getName() + " - " + e.getMessage(),
          null);
      throw new AdminException(
          "GroupManager.deleteGroupById",
          SilverpeasException.ERROR,
          "admin.EX_ERR_DELETE_GROUP",
          "group Id: '" + group.getId() + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }
 /**
  * Get the groups of domain
  *
  * @param ddManager
  * @param sDomainId
  * @return
  * @throws AdminException
  */
 public Group[] getGroupsOfDomain(DomainDriverManager ddManager, String sDomainId)
     throws AdminException {
   try {
     // Get organization
     ddManager.getOrganizationSchema();
     SynchroReport.info(
         "GroupManager.getGroupsOfDomain()",
         "Recherche des groupes du domaine LDAP dans la base...",
         null);
     // Get groups of domain from Silverpeas database
     GroupRow[] grs = ddManager.getOrganization().group.getAllGroupsOfDomain(idAsInt(sDomainId));
     // Convert GroupRow objects in Group Object
     Group[] groups = new Group[grs.length];
     for (int nI = 0; nI < grs.length; nI++) {
       groups[nI] = groupRow2Group(grs[nI]);
       SynchroReport.debug(
           "GroupManager.getGroupsOfDomain()",
           "Groupe trouvé no : "
               + Integer.toString(nI)
               + ", specificID : "
               + groups[nI].getSpecificId()
               + ", desc. : "
               + groups[nI].getDescription(),
           null);
     }
     SynchroReport.info(
         "GroupManager.getGroupsOfDomain()",
         "Récupération de " + grs.length + " groupes du domaine LDAP dans la base",
         null);
     return groups;
   } catch (Exception e) {
     throw new AdminException(
         "GroupManager.getGroupsOfDomain",
         SilverpeasException.ERROR,
         "admin.EX_ERR_GET_GROUPS_OF_DOMAIN",
         "domain Id: '" + sDomainId + "'",
         e);
   } finally {
     ddManager.releaseOrganizationSchema();
   }
 }
  /**
   * Update the given group
   *
   * @param ddManager
   * @param group
   * @param onlyInSilverpeas
   * @return
   * @throws AdminException
   */
  public String updateGroup(DomainDriverManager ddManager, Group group, boolean onlyInSilverpeas)
      throws AdminException {
    ArrayList<String> alRemUsers = new ArrayList<String>();
    ArrayList<String> alAddUsers = new ArrayList<String>();

    if (group == null
        || !StringUtil.isDefined(group.getName())
        || !StringUtil.isDefined(group.getId())) {
      if (group != null) {
        SynchroReport.error(
            "GroupManager.updateGroup()",
            "Problème lors de maj du groupe "
                + group.getSpecificId()
                + " dans la base, ce groupe n'a pas de nom",
            null);
      }
      return "";
    }
    try {
      ddManager.getOrganizationSchema();
      if (group.getDomainId() != null && !onlyInSilverpeas) {
        ddManager.updateGroup(group);
      }
      // Get the group id
      String sGroupId = group.getId();
      String strInfoSycnhro;
      if (group.getSuperGroupId() != null) {
        strInfoSycnhro =
            "Maj du groupe "
                + group.getName()
                + " (père="
                + getGroup(ddManager, group.getSuperGroupId()).getSpecificId()
                + ") dans la base (table ST_Group)...";
      } else {
        strInfoSycnhro =
            "Maj du groupe "
                + group.getName()
                + " (groupe racine) dans la base (table ST_Group)...";
      }
      SynchroReport.info("GroupManager.updateGroup()", strInfoSycnhro, null);
      // Update the group node
      GroupRow gr = group2GroupRow(group);
      ddManager.getOrganization().group.updateGroup(gr);

      // index group information
      ddManager.indexGroup(gr);

      // Update the users if necessary
      SynchroReport.info(
          "GroupManager.updateGroup()",
          "Maj éventuelle des relations du groupe "
              + group.getName()
              + " avec les utilisateurs qui y sont directement inclus (tables ST_Group_User_Rel)",
          null);
      String[] asOldUsersId =
          ddManager.getOrganization().user.getDirectUserIdsOfGroup(idAsInt(sGroupId));

      // Compute the remove users list
      String[] asNewUsersId = group.getUserIds();
      for (String anAsOldUsersId : asOldUsersId) {
        boolean bFound = false;
        for (String anAsNewUsersId : asNewUsersId) {
          if (anAsOldUsersId.equals(anAsNewUsersId)) {
            bFound = true;
          }
        }

        if (!bFound) {
          alRemUsers.add(anAsOldUsersId);
        }
      }

      // Compute the add users list
      for (String anAsNewUsersId : asNewUsersId) {
        boolean bFound = false;
        for (String anAsOldUsersId : asOldUsersId) {
          if (anAsNewUsersId.equals(anAsOldUsersId)) {
            bFound = true;
          }
        }

        if (!bFound) {
          alAddUsers.add(anAsNewUsersId);
        }
      }
      // Remove the users that are not in this group anymore
      for (String alRemUser : alRemUsers) {
        ddManager
            .getOrganization()
            .group
            .removeUserFromGroup(idAsInt(alRemUser), idAsInt(sGroupId));
      }

      // Add the new users of the group
      for (String alAddUser : alAddUsers) {
        ddManager.getOrganization().group.addUserInGroup(idAsInt(alAddUser), idAsInt(sGroupId));
      }

      SynchroReport.info(
          "GroupManager.updateGroup()",
          "Groupe : "
              + group.getName()
              + ", ajout de "
              + alAddUsers.size()
              + " nouveaux utilisateurs, suppression de "
              + alRemUsers.size()
              + " utilisateurs",
          null);
      return sGroupId;
    } catch (Exception e) {
      SynchroReport.error(
          "GroupManager.updateGroup()",
          "problème lors de la maj du groupe " + group.getName() + " - " + e.getMessage(),
          null);
      throw new AdminException(
          "GroupManager.updateGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_UPDATE_GROUP",
          "group Id: '" + group.getId() + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }
  /**
   * Add the given group in Silverpeas
   *
   * @param ddManager
   * @param group
   * @param onlyInSilverpeas
   * @return
   * @throws AdminException
   */
  public String addGroup(DomainDriverManager ddManager, Group group, boolean onlyInSilverpeas)
      throws AdminException {
    if (group == null || !StringUtil.isDefined(group.getName())) {
      if (group != null) {
        SynchroReport.error(
            "GroupManager.addGroup()",
            "Problème lors de l'ajout du groupe "
                + group.getSpecificId()
                + " dans la base, ce groupe n'a pas de nom",
            null);
      }
      return "";
    }

    try {
      ddManager.getOrganizationSchema();
      // Create group in specific domain (if onlyInSilverpeas is not true)
      // if domainId=-1 then group is a silverpeas organization
      if (!onlyInSilverpeas) {
        String specificId;
        if (group.getDomainId() != null) {
          specificId = ddManager.createGroup(group);
          group.setSpecificId(specificId);
        }
      }
      // Create the group node in Silverpeas
      GroupRow gr = group2GroupRow(group);
      if (gr.superGroupId != -1) {
        SynchroReport.info(
            "GroupManager.addGroup()",
            "Ajout du groupe "
                + group.getName()
                + " (père="
                + getGroup(ddManager, group.getSuperGroupId()).getSpecificId()
                + ") dans la table ST_Group",
            null);
      } else { // pas de père
        SynchroReport.info(
            "GroupManager.addGroup()",
            "Ajout du groupe " + group.getName() + " (groupe racine) dans la table ST_Group...",
            null);
      }
      ddManager.getOrganization().group.createGroup(gr);
      String sGroupId = idAsString(gr.id);

      // index group information
      ddManager.indexGroup(gr);

      // Create the links group_user in Silverpeas
      SynchroReport.info(
          "GroupManager.addGroup()",
          "Inclusion des utilisateurs directement associés au groupe "
              + group.getName()
              + " (table ST_Group_User_Rel)",
          null);
      String[] asUserIds = group.getUserIds();
      int nUserAdded = 0;
      for (String asUserId : asUserIds) {
        if (StringUtil.isDefined(asUserId)) {
          ddManager.getOrganization().group.addUserInGroup(idAsInt(asUserId), idAsInt(sGroupId));
          nUserAdded++;
        }
      }
      SynchroReport.info(
          "GroupManager.addGroup()",
          nUserAdded + " utilisateurs ajoutés au groupe " + group.getName() + " dans la base",
          null);
      return sGroupId;
    } catch (Exception e) {
      SynchroReport.error(
          "GroupManager.addGroup()",
          "problème lors de l'ajout du groupe " + group.getName() + " - " + e.getMessage(),
          null);
      throw new AdminException(
          "GroupManager.addGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_ADD_GROUP",
          "group name: '" + group.getName() + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }