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 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;
    }
  }
  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()]);
  }