protected void addSearchByUserRolesCriterion(
      Criteria criteria, Boolean searchByUserRoles, ServiceContext serviceContext)
      throws SystemException {

    if (searchByUserRoles == null) {
      return;
    }

    Criteria assigneesCriteria = criteria.createCriteria("assignees");

    if (!searchByUserRoles) {
      assigneesCriteria.add(Restrictions.eq("assigneeClassName", User.class.getName()));
      assigneesCriteria.add(Restrictions.eq("assigneeClassPK", serviceContext.getUserId()));

      return;
    }

    List<Long> roleIds = RoleRetrievalUtil.getRoleIds(serviceContext);

    List<UserGroupRole> userGroupRoles =
        UserGroupRoleLocalServiceUtil.getUserGroupRoles(serviceContext.getUserId());

    if (userGroupRoles.isEmpty()) {
      assigneesCriteria.add(Restrictions.eq("assigneeClassName", Role.class.getName()));
      assigneesCriteria.add(
          Restrictions.in("assigneeClassPK", roleIds.toArray(new Long[roleIds.size()])));
    } else {
      Junction junction = Restrictions.disjunction();

      junction.add(
          Restrictions.and(
              Restrictions.eq("assigneeClassName", Role.class.getName()),
              Restrictions.in("assigneeClassPK", roleIds.toArray(new Long[roleIds.size()]))));

      for (UserGroupRole userGroupRole : userGroupRoles) {
        junction.add(
            Restrictions.and(
                Restrictions.eq("groupId", userGroupRole.getGroupId()),
                Restrictions.and(
                    Restrictions.eq("assigneeClassName", Role.class.getName()),
                    Restrictions.eq("assigneeClassPK", userGroupRole.getRoleId()))));
      }

      assigneesCriteria.add(junction);
    }
  }
  protected Query doGetPermissionQuery_6(
      long companyId,
      long[] groupIds,
      long userId,
      String className,
      Query query,
      SearchContext searchContext,
      AdvancedPermissionChecker advancedPermissionChecker,
      List<Group> groups,
      List<Role> roles,
      List<UserGroupRole> userGroupRoles,
      Map<Long, List<Role>> groupIdsToRoles)
      throws Exception {

    BooleanQuery permissionQuery = BooleanQueryFactoryUtil.create(searchContext);

    if (userId > 0) {
      permissionQuery.addTerm(Field.USER_ID, userId);
    }

    BooleanQuery groupsQuery = BooleanQueryFactoryUtil.create(searchContext);
    BooleanQuery rolesQuery = BooleanQueryFactoryUtil.create(searchContext);

    for (Role role : roles) {
      String roleName = role.getName();

      if (roleName.equals(RoleConstants.ADMINISTRATOR)) {
        return query;
      }

      if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
          companyId,
          className,
          ResourceConstants.SCOPE_COMPANY,
          String.valueOf(companyId),
          role.getRoleId(),
          ActionKeys.VIEW)) {

        return query;
      }

      if ((role.getType() == RoleConstants.TYPE_REGULAR)
          && ResourcePermissionLocalServiceUtil.hasResourcePermission(
              companyId,
              className,
              ResourceConstants.SCOPE_GROUP_TEMPLATE,
              String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
              role.getRoleId(),
              ActionKeys.VIEW)) {

        return query;
      }

      for (Group group : groups) {
        if (ResourcePermissionLocalServiceUtil.hasResourcePermission(
            companyId,
            className,
            ResourceConstants.SCOPE_GROUP,
            String.valueOf(group.getGroupId()),
            role.getRoleId(),
            ActionKeys.VIEW)) {

          groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
        }

        if ((role.getType() != RoleConstants.TYPE_REGULAR)
            && ResourcePermissionLocalServiceUtil.hasResourcePermission(
                companyId,
                className,
                ResourceConstants.SCOPE_GROUP_TEMPLATE,
                String.valueOf(GroupConstants.DEFAULT_PARENT_GROUP_ID),
                role.getRoleId(),
                ActionKeys.VIEW)) {

          List<Role> groupRoles = groupIdsToRoles.get(group.getGroupId());

          if (groupRoles.contains(role)) {
            groupsQuery.addTerm(Field.GROUP_ID, group.getGroupId());
          }
        }

        if (group.isSite()
            && !roleName.equals(RoleConstants.SITE_MEMBER)
            && (role.getType() == RoleConstants.TYPE_SITE)) {

          rolesQuery.addTerm(
              Field.GROUP_ROLE_ID, group.getGroupId() + StringPool.DASH + role.getRoleId());
        }
      }

      rolesQuery.addTerm(Field.ROLE_ID, role.getRoleId());
    }

    for (Group group : groups) {
      addRequiredMemberRole(group, rolesQuery);
    }

    for (UserGroupRole userGroupRole : userGroupRoles) {
      rolesQuery.addTerm(
          Field.GROUP_ROLE_ID,
          userGroupRole.getGroupId() + StringPool.DASH + userGroupRole.getRoleId());
    }

    if (groupsQuery.hasClauses()) {
      permissionQuery.add(groupsQuery, BooleanClauseOccur.SHOULD);
    }

    if (rolesQuery.hasClauses()) {
      permissionQuery.add(rolesQuery, BooleanClauseOccur.SHOULD);
    }

    BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);

    fullQuery.add(query, BooleanClauseOccur.MUST);
    fullQuery.add(permissionQuery, BooleanClauseOccur.MUST);

    return fullQuery;
  }