public void initFromServer(String lds, String baseDN, String filter, String fallbackSortBy)
     throws AdminException {
   SilverTrace.info("admin", "LDAPTimeStampMSAD.initFromServer()", "root.MSG_GEN_ENTER_METHOD");
   LDAPEntry[] theEntries =
       LDAPUtility.search1000Plus(
           lds,
           baseDN,
           driverSettings.getScope(),
           "(&(" + driverSettings.getTimeStampVar() + ">=" + timeStamp + ")" + filter + ")",
           driverSettings.getTimeStampVar(),
           driverSettings.getGroupAttributes());
   if (theEntries.length > 0) {
     // Problem is : the search1000Plus function sorts normaly by descending
     // order. BUT most LDAP server can't performs this type of order (like
     // Active Directory)
     // So, it may be ordered in the oposite way....
     long firstVal =
         Long.parseLong(
             LDAPUtility.getFirstAttributeValue(theEntries[0], driverSettings.getTimeStampVar()));
     long lastVal =
         Long.parseLong(
             LDAPUtility.getFirstAttributeValue(
                 theEntries[theEntries.length - 1], driverSettings.getTimeStampVar()));
     if (firstVal >= lastVal) {
       lTimeStamp = firstVal;
     } else {
       lTimeStamp = lastVal;
     }
     timeStamp = Long.toString(lTimeStamp);
   }
 }
  public Group[] getAllChangedGroups(String lds, String extraFilter) throws AdminException {
    Vector<LDAPEntry> groupsCur;
    Iterator<LDAPEntry> it;
    int i;
    Hashtable<String, Group> groupsManaged = new Hashtable<String, Group>();
    LDAPEntry[] les = getChildGroupsEntry(lds, null, extraFilter);
    LDAPEntry theGroup;

    Vector<LDAPEntry> groupsIdsSet = new Vector<LDAPEntry>(les.length);
    for (i = 0; i < les.length; i++) {
      groupsIdsSet.add(les[i]);
      groupsManaged.put(les[i].getDN(), translateGroup(lds, les[i]));
    }
    // Go recurs to all group's ancestors
    while (groupsIdsSet.size() > 0) {
      it = groupsIdsSet.iterator();
      groupsCur = new Vector<LDAPEntry>();
      while (it.hasNext()) {
        theGroup = it.next();
        SilverTrace.info(
            "admin",
            "LDAPGroupSamse.getAllChangedGroups()",
            "root.MSG_GEN_PARAM_VALUE",
            "GroupTraite2=" + theGroup.getDN());
        les =
            LDAPUtility.search1000Plus(
                lds,
                driverSettings.getGroupsSpecificGroupsBaseDN(),
                driverSettings.getScope(),
                "(&"
                    + driverSettings.getGroupsFullFilter()
                    + "("
                    + driverSettings.getGroupsMemberField()
                    + "="
                    + LDAPUtility.dblBackSlashesForDNInFilters(theGroup.getDN())
                    + "))",
                driverSettings.getGroupsNameField(),
                driverSettings.getGroupAttributes());
        for (i = 0; i < les.length; i++) {
          SilverTrace.info(
              "admin",
              "LDAPGroupSamse.getAllChangedGroups()",
              "root.MSG_GEN_PARAM_VALUE",
              "GroupFound2=" + les[i].getDN());
          if (!groupsManaged.containsKey(les[i].getDN())) {
            SilverTrace.info(
                "admin",
                "LDAPGroupSamse.getAllChangedGroups()",
                "root.MSG_GEN_PARAM_VALUE",
                "GroupAjoute2=" + les[i].getDN());
            groupsCur.add(les[i]);
            groupsManaged.put(les[i].getDN(), translateGroup(lds, les[i]));
          }
        }
      }
      groupsIdsSet = groupsCur;
    }
    return groupsManaged.values().toArray(new Group[groupsManaged.size()]);
  }
  /**
   * Method declaration
   *
   * @param lds
   * @param groupEntry
   * @return
   * @throws AdminException
   * @see
   */
  @Override
  protected String[] getUserIds(String lds, LDAPEntry groupEntry) throws AdminException {
    Vector<String> usersVector = new Vector<String>();
    LDAPEntry userEntry = null;
    String[] stringVals = null;
    int i;

    SilverTrace.info(
        "admin", "LDAPGroupUniqueDescriptor.getUserIds()", "root.MSG_GEN_ENTER_METHOD");
    stringVals = LDAPUtility.getAttributeValues(groupEntry, driverSettings.getGroupsMemberField());
    for (i = 0; i < stringVals.length; i++) {
      try {
        // userEntry = LDAPUtility.getFirstEntryFromSearch(lds,
        // driverSettings.getLDAPUserBaseDN(), driverSettings.getScope(), "(&" +
        // driverSettings.getUsersFullFilter() + "(distinguishedName=" +
        // LDAPUtility.dblBackSlashesForDNInFilters(stringVals[i]) + "))");
        userEntry =
            LDAPUtility.getFirstEntryFromSearch(
                lds,
                stringVals[i],
                driverSettings.getScope(),
                driverSettings.getUsersFullFilter(),
                driverSettings.getGroupAttributes());
        if (userEntry != null) {
          String userSpecificId =
              LDAPUtility.getFirstAttributeValue(userEntry, driverSettings.getUsersIdField());
          // Verify that the user exist in the scope
          if (LDAPUtility.getFirstEntryFromSearch(
                  lds,
                  driverSettings.getLDAPUserBaseDN(),
                  driverSettings.getScope(),
                  driverSettings.getUsersIdFilter(userSpecificId),
                  driverSettings.getGroupAttributes())
              != null) {
            usersVector.add(userSpecificId);
          }
        }
      } catch (AdminException e) {
        SilverTrace.error(
            "admin",
            "LDAPGroupUniqueDescriptor.getUserIds()",
            "admin.MSG_ERR_LDAP_GENERAL",
            "USER NOT FOUND : " + LDAPUtility.dblBackSlashesForDNInFilters(stringVals[i]),
            e);
      }
    }
    stringVals = null;
    SilverTrace.info("admin", "LDAPGroupUniqueDescriptor.getUserIds()", "root.MSG_GEN_EXIT_METHOD");
    return usersVector.toArray(new String[usersVector.size()]);
  }
  /**
   * Method declaration THIS FUNCTION THROW EXCEPTION ONLY WHEN NO SYNCHRO IS RUNNING
   *
   * @param lds
   * @param parentId
   * @return
   * @throws AdminException
   * @see
   */
  protected Vector<LDAPEntry> getTRUEChildGroupsEntry(
      String lds, String parentId, LDAPEntry theEntry) {
    LDAPEntry childGroupEntry = null;
    Vector<LDAPEntry> entryVector = new Vector<LDAPEntry>();
    String[] stringVals = null;
    int i;

    if ((parentId != null) && (parentId.length() > 0)) {
      SilverTrace.info(
          "admin",
          "LDAPGroupSamse.getTRUEChildGroupsEntry()",
          "root.MSG_GEN_PARAM_VALUE",
          "Root Group Search : " + parentId);
      stringVals = LDAPUtility.getAttributeValues(theEntry, driverSettings.getGroupsMemberField());
      for (i = 0; i < stringVals.length; i++) {
        try {
          childGroupEntry =
              LDAPUtility.getFirstEntryFromSearch(
                  lds,
                  stringVals[i],
                  driverSettings.getScope(),
                  driverSettings.getGroupsFullFilter(),
                  driverSettings.getGroupAttributes());
          if (childGroupEntry != null) {
            // Verify that the group exist in the scope
            String groupSpecificId =
                LDAPUtility.getFirstAttributeValue(
                    childGroupEntry, driverSettings.getGroupsIdField());
            if (LDAPUtility.getFirstEntryFromSearch(
                    lds,
                    driverSettings.getGroupsSpecificGroupsBaseDN(),
                    driverSettings.getScope(),
                    driverSettings.getGroupsIdFilter(groupSpecificId),
                    driverSettings.getGroupAttributes())
                != null) {
              entryVector.add(childGroupEntry);
            }
          }
        } catch (AdminException e) {
          SilverTrace.error(
              "admin",
              "LDAPGroupSamse.getTRUEChildGroupsEntry()",
              "admin.MSG_ERR_LDAP_GENERAL",
              "GROUP NOT FOUND : " + stringVals[i],
              e);
        }
      }
    }
    return entryVector;
  }
  /**
   * Method declaration THIS FUNCTION THROW EXCEPTION ONLY WHEN NO SYNCHRO IS RUNNING
   *
   * @param lds
   * @param parentId
   * @return
   * @throws AdminException
   * @see
   */
  protected LDAPEntry[] getChildGroupsEntry(String lds, String parentId, String extraFilter)
      throws AdminException {
    if ((parentId != null) && (parentId.length() > 0)) { // ALL ROOT GROUPS
      return ArrayUtil.EMPTY_LDAP_ENTRY_ARRAY;
    } else {
      LDAPEntry[] theEntries = null;
      String theFilter;

      if ((extraFilter != null) && (extraFilter.length() > 0)) {
        theFilter = "(&" + extraFilter + driverSettings.getGroupsFullFilter() + ")";
      } else {
        theFilter = driverSettings.getGroupsFullFilter();
      }
      try {
        SilverTrace.info(
            "admin",
            "LDAPGroupSamse.getChildGroupsEntry()",
            "root.MSG_GEN_PARAM_VALUE",
            "Root Group Search");
        theEntries =
            LDAPUtility.search1000Plus(
                lds,
                driverSettings.getGroupsSpecificGroupsBaseDN(),
                driverSettings.getScope(),
                theFilter,
                driverSettings.getGroupsNameField(),
                driverSettings.getGroupAttributes());
        SynchroReport.debug(
            "LDAPGroupSamse.getChildGroupsEntry()",
            "Récupération de " + theEntries.length + " groupes racine",
            null);
      } catch (AdminException e) {
        if (synchroInProcess) {
          SilverTrace.warn(
              "admin",
              "LDAPGroupSamse.getChildGroupsEntry()",
              "admin.EX_ERR_CHILD_GROUPS",
              "ParentGroupId=" + parentId,
              e);
          append("PB getting Group's subgroups : ").append(parentId).append("\n");
          SynchroReport.error(
              "LDAPGroupSamse.getChildGroupsEntry()",
              "Erreur lors de la récupération des groupes racine (parentId = " + parentId + ")",
              e);
        } else {
          throw e;
        }
      }
      return theEntries;
    }
  }
  /**
   * Method declaration
   *
   * @param lds
   * @param groupEntry
   * @return
   * @throws AdminException
   * @see
   */
  protected String[] getUserIds(String lds, LDAPEntry groupEntry) throws AdminException {
    HashSet<String> usersManaged = new HashSet<String>();
    HashSet<String> groupsManaged = new HashSet<String>();
    Vector<LDAPEntry> groupsSet = new Vector<LDAPEntry>();
    Vector<LDAPEntry> groupsCur;
    Iterator<LDAPEntry> it;
    LDAPEntry curGroup;
    String grId;

    groupsSet.add(groupEntry);
    while (groupsSet.size() > 0) {
      it = groupsSet.iterator();
      groupsCur = new Vector<LDAPEntry>();
      while (it.hasNext()) {
        curGroup = it.next();
        if (curGroup != null) {
          grId = "???";
          try {
            grId = LDAPUtility.getFirstAttributeValue(curGroup, driverSettings.getGroupsIdField());
            if (!groupsManaged.contains(grId)) {
              groupsManaged.add(grId);
              usersManaged.addAll(getTRUEUserIds(lds, curGroup));
              // Pas de sous groupes chez SAMSE
              // groupsCur.addAll(getTRUEChildGroupsEntry(lds, grId, curGroup));
            }
          } catch (AdminException e) {
            SilverTrace.info(
                "admin",
                "LDAPGroupAllRoot.getUserIds()",
                "admin.MSG_ERR_LDAP_GENERAL",
                "GROUP NOT FOUND : " + grId,
                e);
          }
        }
      }
      groupsSet = groupsCur;
    }
    return usersManaged.toArray(new String[usersManaged.size()]);
  }
  protected Vector<String> getTRUEUserIds(String lds, LDAPEntry groupEntry) throws AdminException {
    SilverTrace.info(
        "admin",
        "LDAPGroupSamse.getTRUEUserIds()",
        "root.MSG_GEN_ENTER_METHOD",
        "lds = " + lds + ", group = " + groupEntry.getDN());

    Vector<String> usersVector = new Vector<String>();
    String groupsMemberField = driverSettings.getGroupsMemberField();

    // retrieve all memberUid
    String[] stringVals = LDAPUtility.getAttributeValues(groupEntry, groupsMemberField);
    for (int i = 0; i < stringVals.length; i++) {
      SilverTrace.info(
          "admin",
          "LDAPGroupSamse.getTRUEUserIds()",
          "root.MSG_GEN_PARAM_VALUE",
          "stringVals[" + i + "] = " + stringVals[i]);
      usersVector.add(stringVals[i]);
    }
    stringVals = null;
    SilverTrace.info("admin", "LDAPGroupSamse.getTRUEUserIds()", "root.MSG_GEN_EXIT_METHOD");
    return usersVector;
  }
  protected String[] getMemberGroupIds(String lds, String memberId, boolean isGroup)
      throws AdminException {
    Vector<String> groupsVector = new Vector<String>();
    LDAPEntry[] theEntries = null;
    LDAPEntry memberEntry = null;
    int i;

    SilverTrace.info(
        "admin",
        "LDAPGroupUniqueDescriptor.getMemberGroupIds()",
        "root.MSG_GEN_ENTER_METHOD",
        "MemberId=" + memberId + ", isGroup=" + isGroup);
    if (isGroup) {
      memberEntry =
          LDAPUtility.getFirstEntryFromSearch(
              lds,
              driverSettings.getGroupsSpecificGroupsBaseDN(),
              driverSettings.getScope(),
              driverSettings.getGroupsIdFilter(memberId),
              driverSettings.getGroupAttributes());
    } else {
      memberEntry =
          LDAPUtility.getFirstEntryFromSearch(
              lds,
              driverSettings.getLDAPUserBaseDN(),
              driverSettings.getScope(),
              driverSettings.getUsersIdFilter(memberId),
              driverSettings.getGroupAttributes());
    }
    if (memberEntry == null) {
      throw new AdminException(
          "LDAPGroupUniqueDescriptor.getMemberGroupIds",
          SilverpeasException.ERROR,
          "admin.EX_ERR_LDAP_USER_ENTRY_ISNULL",
          "Id=" + memberId + " IsGroup=" + isGroup);
    }
    theEntries =
        LDAPUtility.search1000Plus(
            lds,
            driverSettings.getGroupsSpecificGroupsBaseDN(),
            driverSettings.getScope(),
            "(&"
                + driverSettings.getGroupsFullFilter()
                + "("
                + driverSettings.getGroupsMemberField()
                + "="
                + LDAPUtility.dblBackSlashesForDNInFilters(memberEntry.getDN())
                + "))",
            driverSettings.getGroupsNameField(),
            driverSettings.getGroupAttributes());
    for (i = 0; i < theEntries.length; i++) {
      SilverTrace.info(
          "admin",
          "LDAPGroupUniqueDescriptor.getMemberGroupIds()",
          "root.MSG_GEN_PARAM_VALUE",
          "GroupFound=" + theEntries[i].getDN());
      groupsVector.add(
          LDAPUtility.getFirstAttributeValue(theEntries[i], driverSettings.getGroupsIdField()));
    }
    return groupsVector.toArray(new String[groupsVector.size()]);
  }
  /**
   * Method declaration THIS FUNCTION THROW EXCEPTION ONLY WHEN NO SYNCHRO IS RUNNING
   *
   * @param lds
   * @param parentId
   * @return
   * @throws AdminException
   * @see
   */
  @Override
  protected LDAPEntry[] getChildGroupsEntry(String lds, String parentId, String extraFilter)
      throws AdminException {
    LDAPEntry theEntry = null;
    LDAPEntry childGroupEntry = null;
    LDAPEntry parentGroupEntry = null;
    Vector<LDAPEntry> entryVector = new Vector<LDAPEntry>();
    String[] stringVals = null;
    LDAPEntry[] theEntries = null;
    int i;
    String theFilter;

    try {
      if ((parentId != null) && (parentId.length() > 0)) {
        SilverTrace.info(
            "admin",
            "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
            "root.MSG_GEN_PARAM_VALUE",
            "Root Group Search : " + parentId);
        theEntry = getGroupEntry(lds, parentId);
        stringVals =
            LDAPUtility.getAttributeValues(theEntry, driverSettings.getGroupsMemberField());
        for (i = 0; i < stringVals.length; i++) {
          try {
            if ((extraFilter != null) && (extraFilter.length() > 0)) {
              theFilter = "(&" + extraFilter + driverSettings.getGroupsFullFilter() + ")";
            } else {
              theFilter = driverSettings.getGroupsFullFilter();
            }
            childGroupEntry =
                LDAPUtility.getFirstEntryFromSearch(
                    lds,
                    stringVals[i],
                    driverSettings.getScope(),
                    theFilter,
                    driverSettings.getGroupAttributes());
            if (childGroupEntry != null) {
              // Verify that the group exist in the scope
              String groupSpecificId =
                  LDAPUtility.getFirstAttributeValue(
                      childGroupEntry, driverSettings.getGroupsIdField());
              if (LDAPUtility.getFirstEntryFromSearch(
                      lds,
                      driverSettings.getGroupsSpecificGroupsBaseDN(),
                      driverSettings.getScope(),
                      driverSettings.getGroupsIdFilter(groupSpecificId),
                      driverSettings.getGroupAttributes())
                  != null) {
                entryVector.add(childGroupEntry);
              }
            }
          } catch (AdminException e) {
            SilverTrace.error(
                "admin",
                "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
                "admin.MSG_ERR_LDAP_GENERAL",
                "GROUP NOT FOUND : " + stringVals[i],
                e);
          }
        }
      } else // Retreives the ROOT groups : the groups that are under the base
      // DN but that are not member of another group...
      {
        if ((extraFilter != null) && (extraFilter.length() > 0)) {
          theFilter = "(&" + extraFilter + driverSettings.getGroupsFullFilter() + ")";
        } else {
          theFilter = driverSettings.getGroupsFullFilter();
        }
        SilverTrace.info(
            "admin",
            "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
            "root.MSG_GEN_PARAM_VALUE",
            "Root Group Search");
        theEntries =
            LDAPUtility.search1000Plus(
                lds,
                driverSettings.getGroupsSpecificGroupsBaseDN(),
                driverSettings.getScope(),
                theFilter,
                driverSettings.getGroupsNameField(),
                driverSettings.getGroupAttributes());
        SynchroReport.debug(
            "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
            "Récupération de "
                + theEntries.length
                + " groupes en tout, recherche des groupes racine...",
            null);
        for (i = 0; i < theEntries.length; i++) {
          // Search for groups that have at least one member attribute that
          // point to the group
          try {
            parentGroupEntry =
                LDAPUtility.getFirstEntryFromSearch(
                    lds,
                    driverSettings.getGroupsSpecificGroupsBaseDN(),
                    driverSettings.getScope(),
                    "(&"
                        + driverSettings.getGroupsFullFilter()
                        + "("
                        + driverSettings.getGroupsMemberField()
                        + "="
                        + LDAPUtility.dblBackSlashesForDNInFilters(theEntries[i].getDN())
                        + "))",
                    driverSettings.getGroupAttributes());
          } catch (AdminException e) {
            SilverTrace.error(
                "admin",
                "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
                "admin.MSG_ERR_LDAP_GENERAL",
                "IS ROOT GROUP ? : " + theEntries[i].getDN(),
                e);
            parentGroupEntry = null; // If query failed, set this group as a
            // root group
          }
          if (parentGroupEntry == null) // No parent...
          {
            entryVector.add(theEntries[i]);
          }
        }
        theEntries = null;
      }
    } catch (AdminException e) {
      if (synchroInProcess) {
        SilverTrace.warn(
            "admin",
            "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
            "admin.EX_ERR_CHILD_GROUPS",
            "ParentGroupId=" + parentId,
            e);
        append("PB getting Group's subgroups : ").append(parentId).append("\n");
        if (parentId == null)
          SynchroReport.error(
              "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
              "Erreur lors de la récupération des groupes racine",
              e);
        else
          SynchroReport.error(
              "LDAPGroupUniqueDescriptor.getChildGroupsEntry()",
              "Erreur lors de la récupération des groupes fils du groupe " + parentId,
              e);
      } else {
        throw e;
      }
    }
    return entryVector.toArray(new LDAPEntry[entryVector.size()]);
  }