/**
   * Checks that the current user is permitted to use the group for Remote Staging.
   *
   * @param groupId the primary key of the group
   * @throws PortalException if a portal exception occurred
   */
  @Override
  public void checkRemoteStagingGroup(long groupId) throws PortalException {
    Group group = getGroup(groupId);

    PermissionChecker permissionChecker = getPermissionChecker();

    if (group.getCompanyId() != permissionChecker.getCompanyId()) {
      throw new NoSuchGroupException(
          "Group " + groupId + " does not belong in company " + permissionChecker.getCompanyId());
    }
  }
  /**
   * Returns a range of all the site groups for which the user has control panel access.
   *
   * @param portlets the portlets to manage
   * @param max the upper bound of the range of groups to consider (not inclusive)
   * @return the range of site groups for which the user has Control Panel access
   * @throws PortalException if a portal exception occurred
   */
  @Override
  public List<Group> getManageableSiteGroups(Collection<Portlet> portlets, int max)
      throws PortalException {

    PermissionChecker permissionChecker = getPermissionChecker();

    if (permissionChecker.isCompanyAdmin()) {
      LinkedHashMap<String, Object> params = new LinkedHashMap<>();

      params.put("site", Boolean.TRUE);

      return ListUtil.unique(
          groupLocalService.search(
              permissionChecker.getCompanyId(), null, null, null, params, true, 0, max));
    }

    Set<Group> groups = new LinkedHashSet<>();

    List<Group> userSitesGroups = getUserSitesGroups(null, max);

    Iterator<Group> itr = userSitesGroups.iterator();

    while (itr.hasNext()) {
      Group group = itr.next();

      if (group.isSite()
          && PortletPermissionUtil.hasControlPanelAccessPermission(
              permissionChecker, group.getGroupId(), portlets)) {

        groups.add(group);
      }
    }

    return new ArrayList<>(groups);
  }
  @Override
  protected boolean hasPermissionImplicitlyGranted(
      PermissionChecker permissionChecker, Group group, Portlet portlet) throws Exception {

    if (WorkflowInstanceManagerUtil.getWorkflowInstanceCount(
            permissionChecker.getCompanyId(), permissionChecker.getUserId(), null, null, null)
        > 0) {

      return true;
    }

    return super.hasPermissionImplicitlyGranted(permissionChecker, group, portlet);
  }
  @Override
  public boolean hasAddPermission(
      PermissionChecker permissionChecker, long groupId, long classTypeId) throws Exception {

    ServiceContext serviceContext = new ServiceContext();

    serviceContext.setCompanyId(permissionChecker.getCompanyId());

    CalendarResource calendarResource =
        CalendarResourceUtil.getScopeGroupCalendarResource(groupId, serviceContext);

    if (calendarResource == null) {
      return false;
    }

    Calendar calendar = calendarResource.getDefaultCalendar();

    return CalendarPermission.contains(
        permissionChecker, calendar.getCalendarId(), CalendarActionKeys.MANAGE_BOOKINGS);
  }
  @Override
  public boolean contains(
      PermissionChecker permissionChecker, long userId, long[] organizationIds, String actionId) {

    try {
      User user = null;

      if (userId != ResourceConstants.PRIMKEY_DNE) {
        user = UserLocalServiceUtil.getUserById(userId);

        if ((actionId.equals(ActionKeys.DELETE)
                || actionId.equals(ActionKeys.IMPERSONATE)
                || actionId.equals(ActionKeys.PERMISSIONS)
                || actionId.equals(ActionKeys.UPDATE)
                || actionId.equals(ActionKeys.VIEW))
            && !permissionChecker.isOmniadmin()
            && (PortalUtil.isOmniadmin(user)
                || (!permissionChecker.isCompanyAdmin() && PortalUtil.isCompanyAdmin(user)))) {

          return false;
        }

        Contact contact = user.getContact();

        if (permissionChecker.hasOwnerPermission(
                permissionChecker.getCompanyId(),
                User.class.getName(),
                userId,
                contact.getUserId(),
                actionId)
            || (permissionChecker.getUserId() == userId)) {

          return true;
        }
      }

      if (permissionChecker.hasPermission(0, User.class.getName(), userId, actionId)) {

        return true;
      }

      if (user == null) {
        return false;
      }

      if (organizationIds == null) {
        organizationIds = user.getOrganizationIds();
      }

      for (long organizationId : organizationIds) {
        Organization organization = OrganizationLocalServiceUtil.getOrganization(organizationId);

        if (OrganizationPermissionUtil.contains(
            permissionChecker, organization, ActionKeys.MANAGE_USERS)) {

          if (permissionChecker.getUserId() == user.getUserId()) {
            return true;
          }

          Group organizationGroup = organization.getGroup();

          // Organization administrators can only manage normal users.
          // Owners can only manage normal users and administrators.

          if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
              user.getUserId(),
              organizationGroup.getGroupId(),
              RoleConstants.ORGANIZATION_OWNER,
              true)) {

            continue;
          } else if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
                  user.getUserId(),
                  organizationGroup.getGroupId(),
                  RoleConstants.ORGANIZATION_ADMINISTRATOR,
                  true)
              && !UserGroupRoleLocalServiceUtil.hasUserGroupRole(
                  permissionChecker.getUserId(),
                  organizationGroup.getGroupId(),
                  RoleConstants.ORGANIZATION_OWNER,
                  true)) {

            continue;
          }

          return true;
        }
      }
    } catch (Exception e) {
      _log.error(e, e);
    }

    return false;
  }