@Override
  public Pair<List<IAMGroup>, Integer> listIAMGroups(
      Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize) {
    if (iamGroupId != null) {
      IAMGroup group = _aclGroupDao.findById(iamGroupId);
      if (group == null) {
        throw new InvalidParameterValueException("Unable to find acl group by id " + iamGroupId);
      }
    }

    Filter searchFilter = new Filter(IAMGroupVO.class, "id", true, startIndex, pageSize);

    SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder();
    sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ);
    sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE);
    sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);

    SearchCriteria<IAMGroupVO> sc = sb.create();

    if (iamGroupName != null) {
      sc.setParameters("name", iamGroupName);
    }

    if (iamGroupId != null) {
      sc.setParameters("id", iamGroupId);
    }

    sc.setParameters("path", path + "%");

    Pair<List<IAMGroupVO>, Integer> groups = _aclGroupDao.searchAndCount(sc, searchFilter);
    return new Pair<List<IAMGroup>, Integer>(
        new ArrayList<IAMGroup>(groups.first()), groups.second());
  }
  @Override
  public List<IAMGroup> listParentIAMGroups(long groupId) {
    IAMGroup group = _aclGroupDao.findById(groupId);
    if (group == null) {
      throw new InvalidParameterValueException("Unable to find acl group by id " + groupId);
    }

    String path = group.getPath();
    List<String> pathList = new ArrayList<String>();

    String[] parts = path.split("/");

    for (String part : parts) {
      int start = path.indexOf(part);
      if (start > 0) {
        String subPath = path.substring(0, start);
        pathList.add(subPath);
      }
    }

    if (pathList.isEmpty()) {
      return new ArrayList<IAMGroup>();
    }

    SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder();
    sb.and("paths", sb.entity().getPath(), SearchCriteria.Op.IN);

    SearchCriteria<IAMGroupVO> sc = sb.create();
    sc.setParameters("paths", pathList.toArray());

    List<IAMGroupVO> groups = _aclGroupDao.search(sc, null);

    return new ArrayList<IAMGroup>(groups);
  }
  @SuppressWarnings("unchecked")
  @Override
  public List<IAMGroup> listIAMGroups(long accountId) {

    GenericSearchBuilder<IAMGroupAccountMapVO, Long> groupSB =
        _aclGroupAccountMapDao.createSearchBuilder(Long.class);
    groupSB.selectFields(groupSB.entity().getAclGroupId());
    groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
    SearchCriteria<Long> groupSc = groupSB.create();
    groupSc.setParameters("account", accountId);

    List<Long> groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null);

    SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder();
    sb.and("ids", sb.entity().getId(), Op.IN);
    SearchCriteria<IAMGroupVO> sc = sb.create();
    sc.setParameters("ids", groupIds.toArray(new Object[groupIds.size()]));
    @SuppressWarnings("rawtypes")
    List groups = _aclGroupDao.search(sc, null);
    return groups;
  }