@Override
  public Iterator<IEntityGroup> findParentGroups(IGroupMember member) throws GroupsException {

    /*
     * This method has the potential to be called A LOT, especially if
     * there's a lot of portal data (portlets & groups).  It's important
     * not to waste time on nonsensical checks.
     */

    if (!IPERSON_CLASS.equals(member.getLeafType())) {
      // This is going to happen;  GaP code is not responsible for
      // knowing that PAGS only supports groups of IPerson (we are).
      return Collections.emptyIterator();
    }

    logger.debug("finding containing groups for member key {}", member.getKey());

    final Set<IEntityGroup> set = Collections.emptySet();
    Iterator<IEntityGroup> rslt = set.iterator(); // default

    if (member.isGroup()) {
      // PAGS groups may only contain other PAGS groups (and people, of course)
      final IEntityGroup ieg = (IEntityGroup) member;
      if (PagsService.SERVICE_NAME_PAGS.equals(ieg.getServiceName().toString())) {
        rslt = findParentGroupsForGroup((IEntityGroup) member);
      }
    } else {
      rslt = findParentGroupsForEntity((IEntity) member);
    }

    return rslt;
  }
  @Override
  public boolean contains(IEntityGroup group, IGroupMember member) {

    /*
     * This method has the potential to be called A LOT, especially if
     * there's a lot of portal data (portlets & groups).  It's important
     * not to waste time on nonsensical checks.
     */

    if (!IPERSON_CLASS.equals(member.getLeafType())) {
      // Maybe this call to contains() shouldn't even happen, since
      // group.getLeafType() is (presumably) IPerson.class.
      return false;
    }

    if (member.isGroup()) {
      // PAGS groups may only contain other PAGS groups (and people, of course)
      final IEntityGroup ieg = (IEntityGroup) member;
      if (!PagsService.SERVICE_NAME_PAGS.equals(ieg.getServiceName().toString())) {
        return false;
      }
    }

    final MembershipCacheKey cacheKey =
        new MembershipCacheKey(group.getEntityIdentifier(), member.getEntityIdentifier());
    Element element = membershipCache.get(cacheKey);
    if (element == null) {

      logger.debug(
          "Checking if group {} contains member {}/{}",
          group.getName(),
          member.getKey(),
          member.getLeafType().getSimpleName());

      boolean answer = false; // default
      final PagsGroup groupDef = convertEntityToGroupDef(group);
      if (member.isGroup()) {
        final String key = ((IEntityGroup) member).getLocalKey();
        answer = groupDef.hasMember(key);
      } else {
        try {
          final IPersonAttributeDao pa = PersonAttributeDaoLocator.getPersonAttributeDao();
          final IPersonAttributes personAttributes = pa.getPerson(member.getKey());

          if (personAttributes != null) {
            final RestrictedPerson rp = PersonFactory.createRestrictedPerson();
            rp.setAttributes(personAttributes.getAttributes());
            answer = groupDef.contains(rp);
          }
        } catch (Exception ex) {
          logger.error(
              "Exception acquiring attributes for member "
                  + member
                  + " while checking if group "
                  + group
                  + " contains this member.",
              ex);
          return false;
        }
      }

      element = new Element(cacheKey, answer);
      membershipCache.put(element);
    }

    return (Boolean) element.getObjectValue();
  }