docs: @Nonnull
    public EChange unassignRoleFromAllUserGroups (@Nullable final String sRoleID)
    {
      if (StringHelper.hasNoText (sRoleID))
        return EChange.UNCHANGED;
  
      final ICommonsList <IUserGroup> aAffectedUserGroups = new CommonsArrayList <> ();
      m_aRWLock.writeLock ().lock ();
      try
      {
        EChange eChange = EChange.UNCHANGED;
        for (final UserGroup aUserGroup : internalDirectGetAll ())
          if (aUserGroup.unassignRole (sRoleID).isChanged ())
          {
            aAffectedUserGroups.add (aUserGroup);
            BusinessObjectHelper.setLastModificationNow (aUserGroup);
            internalUpdateItem (aUserGroup);
            eChange = EChange.CHANGED;
          }
        if (eChange.isUnchanged ())
          return EChange.UNCHANGED;
      }
      finally
      {
        m_aRWLock.writeLock ().unlock ();
      }
      AuditHelper.onAuditModifySuccess (UserGroup.OT, "unassign-role-from-all-usergroups", sRoleID);
  
      // Execute callback as the very last action
      for (final IUserGroup aUserGroup : aAffectedUserGroups)
        m_aCallbacks.forEach (aCB -> aCB.onUserGroupRoleAssignment (aUserGroup, sRoleID, false));
  
      return EChange.CHANGED;
    }
  
    /**
     * Get a collection of all user groups to which a certain role is assigned to.
     *
     * @param sRoleID
     *        The role ID to search
     * @return A non-<code>null</code>but may be empty collection with all
     *         matching user groups.
     */
    @Nonnull
    @ReturnsMutableCopy
    public ICommonsList <IUserGroup> getAllUserGroupsWithAssignedRole (@Nullable final String sRoleID)
    {
      if (StringHelper.hasNoText (sRoleID))
        return getNone ();
  
      return getAll (aUserGroup -> aUserGroup.containsRoleID (sRoleID));
    }