package com.airlock.iam.admin.application.configuration;

import com.airlock.iam.admin.application.service.access.ActionBasedAccessController;
import com.airlock.iam.admin.domain.model.administrator.permissions.Actions;
import com.airlock.iam.base.infrastructure.reflection.ReflectionHelper;
import com.airlock.iam.common.application.configuration.authorization.ResourceAccessController;
import com.airlock.iam.common.application.configuration.authorization.ResourceAccessControllerAccessRule;
import com.airlock.iam.common.application.configuration.authorization.ResourceAccessController.ResourceAccessControllerBuilder;
import com.airlock.iam.common.application.configuration.authorization.ResourceAccessControllerAccessRule.ResourceAccessControllerAccessRuleBuilder;
import com.airlock.iam.core.misc.authorization.AccessController;
import com.airlock.iam.core.misc.authorization.CombiningAccessController;
import com.airlock.iam.plugin.api.annotation.config.Groups;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.lifecycle.AfterConfigActivation;
import com.airlock.iam.plugin.api.annotation.property.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import com.airlock.iam.plugin.framework.application.service.builder.plugin.PluginPropertyBuilderInitializer;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Plugin(
   description = "Defines access control for the Adminapp REST API. REST calls are permitted whenever the corresponding rule defined in this plugin <em>or</em> a rule defined within the REST Access Controller is fulfilled.",
   displayName = "Role-based Access Control",
   typeShortName = "RoleBasedAccessControl"
)
@Groups(
   groupSequence = {
         "REST API",
         "User Management",
         "Password Management",
         "Authentication Token Management",
         "Maintenance Message Management",
         "Administrator Management",
         "Configuration Management",
         "Technical Clients Management",
         "Miscellaneous"
   },
   openGroups = "REST API"
)
public class RoleBasedAccessControllerConfig implements AdminappAccessControllerConfig {
   public static final String ROLE_BASED_ACCESS_CONTROL_DISPLAY_NAME = "Role-based Access Control";
   public static final String NO_RESTRICTION = "NO RESTRICTION";
   protected static final String REST_ACCESS_CONTROL_SETTINGS = "REST API";
   public static final String USER_MANAGEMENT_ACCESS_CONTROL_SETTINGS = "User Management";
   protected static final String PASSWORD_MANAGEMENT_ACCESS_CONTROL_SETTINGS = "Password Management";
   protected static final String TOKEN_MANAGEMENT_ACCESS_CONTROL_SETTINGS = "Authentication Token Management";
   protected static final String TECHNICAL_CLIENTS_SETTINGS = "Technical Clients Management";
   protected static final String MAINTENANCE_MESSAGE_MANAGEMENT_ACCESS_CONTROL_SETTINGS = "Maintenance Message Management";
   protected static final String ADMINISTRATOR_MANAGEMENT_ACCESS_CONTROL_SETTINGS = "Administrator Management";
   protected static final String CONFIGURATION_MANAGEMENT_ACCESS_CONTROL_SETTINGS = "Configuration Management";
   protected static final String MISC_ACCESS_CONTROL_SETTINGS = "Miscellaneous";
   private static final String HELP_TEXT = "At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.";
   @PluginProperty(
      displayName = "REST Access Controller",
      description = "The access controller plugin checking REST resources are allowed for the logged in administrator. The REST access controller can only allow additional access to REST resources, but not restrict it more than defined by the role based access rules below.",
      optional = true
   )
   @GroupProperty(groupIdentifier = "REST API")
   private ResourceAccessController restServiceAccessController;
   public static final String REST_ACCESS_CONTROLLER_DISPLAY_NAME = "REST Access Controller";
   @StringProperty(
      displayName = "List Users",
      optional = true,
      description = "Roles required to list and search for users. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String listUsers;
   public static final String LIST_USERS_DISPLAY_NAME = "List Users";
   @StringProperty(
      displayName = "View User Details",
      optional = true,
      description = "Roles required to view user details. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String viewUser;
   @StringProperty(
      displayName = "View User Logs",
      optional = true,
      description = "Roles required to view user related logs in the user details. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String viewUserLogs;
   @StringProperty(
      displayName = "View User Context Data",
      optional = true,
      description = "Roles required to view user context data. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String viewContextData;
   @PluginListProperty(
      optional = true,
      displayName = "View User Context Data (fine-grained)",
      description = "Fine-grained access rules for context data fields view. Has precedence over 'View User Context Data'."
   )
   @GroupProperty(groupIdentifier = "User Management")
   private List<ContextDataAccessRule> detailedViewContextData;
   @StringProperty(
      displayName = "Display User Management Extensions",
      optional = true,
      description = "Administrators with these roles that can see User Management Extensions. </br><b>The JavaScript file that contains the User Management Extensions always has the same accessibility as the rest of the Adminapp UI and can be accessed by unauthenticated users/administrators.</b></br>At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String displayUserManagementExtensions;
   @PluginListProperty(
      optional = true,
      displayName = "Display User Management Extensions (fine-grained)",
      description = "Fine-grained display rules for User Management Extensions. Has precedence over 'Display User Management Extensions'.</br><b>This setting does not influence the delivered JavaScript for the User Management Extension. It will always contain the code for all User Management Extensions.</b>"
   )
   @GroupProperty(groupIdentifier = "User Management")
   private List<UserManagementExtensionAccessRuleConfig> detailedDisplayUserManagementExtensions;
   @StringProperty(
      displayName = "Edit User Details",
      optional = true,
      description = "Roles required to edit user details. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String editUser;
   private static final String EDIT_USER_DETAILS_DISPLAY_NAME = "Edit User Details";
   @PluginListProperty(
      optional = true,
      displayName = "Edit User Context Data",
      description = "Fine-grained access rules for context data fields editing. 'Edit User Details' has precedence over these access rules."
   )
   @GroupProperty(groupIdentifier = "User Management")
   private List<ContextDataAccessRule> detailedEditContextData;
   @StringProperty(
      displayName = "Edit Username",
      optional = true,
      description = "Roles required to edit the user name. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String editUsername;
   @StringProperty(
      displayName = "Delete User",
      optional = true,
      description = "Roles required to delete a user. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String deleteUser;
   @StringProperty(
      displayName = "Add New User",
      optional = true,
      description = "Roles required to add users. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String createUser;
   @StringProperty(
      displayName = "Lock User",
      optional = true,
      description = "Roles required to lock a user. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String lockUser;
   @StringProperty(
      displayName = "Unlock User",
      optional = true,
      description = "Roles required to unlock a user. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String unlockUser;
   @StringProperty(
      displayName = "Manage OAuth 2.0 User Consents",
      optional = true,
      description = "Roles required to manage OAuth 2.0 consents for a user. If granted, takes precedence over \"Edit User Details\". At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "User Management")
   private String manageOAuth2Consents;
   @StringProperty(
      displayName = "Order Password Letter",
      optional = true,
      description = "Roles required to order a password letter. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Password Management")
   private String orderPassword;
   @StringProperty(
      displayName = "Cancel Password Letter Order",
      optional = true,
      description = "Roles required to cancel an order for a password letter. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Password Management")
   private String unorderPassword;
   @StringProperty(
      displayName = "Delete User Password",
      optional = true,
      description = "Roles required to delete a user's password. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Password Management")
   private String deletePassword;
   @StringProperty(
      displayName = "Generate Or Set User Password",
      optional = true,
      description = "Roles required to generate or set a user's password. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Password Management")
   private String generatePassword;
   @StringProperty(
      displayName = "Trigger Password Reset",
      optional = true,
      description = "Roles required to trigger a password reset. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Password Management")
   private String triggerPasswordReset;
   @StringProperty(
      displayName = "View Authentication Token",
      optional = true,
      description = "Roles required to view token details on users or in the token manager. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String viewToken;
   @StringProperty(
      displayName = "Edit Authentication Token",
      optional = true,
      description = "Roles required to edit a token. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String editToken;
   @StringProperty(
      displayName = "Order New Authentication Token",
      optional = true,
      description = "Roles required to order a new token. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String orderNewToken;
   @StringProperty(
      displayName = "Cancel Authentication Token Order",
      optional = true,
      description = "Roles required to cancel a token order. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String unorderNewToken;
   @StringProperty(
      displayName = "Delete Authentication Token",
      optional = true,
      description = "Roles required to delete a token. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String deleteToken;
   @StringProperty(
      displayName = "Activate Authentication Token",
      optional = true,
      description = "Roles required to activate a token. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String activateToken;
   @StringProperty(
      displayName = "Deactivate Authentication Token",
      optional = true,
      description = "Roles required to deactivate a token. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String deactivateToken;
   @StringProperty(
      displayName = "Generate Token Activation Key IAK",
      optional = true,
      description = "Roles required to generate an IAK activation key. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String generateTokenIak;
   @StringProperty(
      displayName = "Token Management",
      optional = true,
      description = "Roles required to manage (import) tokens. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String manageTokens;
   @StringProperty(
      displayName = "View OATH OTP Token Secret",
      optional = true,
      description = "Roles required to view the shared secret of OATH OTP tokens. At least one of the listed, comma-separated roles are sufficient. No value means not allowed for anyone. 'NO RESTRICTION' allows access to everyone.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String viewOathOtpTokenSecret;
   @StringProperty(
      displayName = "View Airlock 2FA Activation Secret",
      optional = true,
      description = "Roles required to view the Airlock 2FA activation code(s), e.g. when creating or fetching Airlock 2FA activation letters. At least one of the listed, comma-separated roles are sufficient. No value means not allowed for anyone. 'NO RESTRICTION' allows access to everyone.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String viewAirlock2FAActivationSecret;
   @StringProperty(
      displayName = "View Cronto Activation Secret",
      optional = true,
      description = "Roles required to view the Cronto activation code(s). At least one of the listed, comma-separated roles are sufficient. No value means not allowed for anyone. 'NO RESTRICTION' allows access to everyone.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Authentication Token Management")
   private String viewCrontoActivationSecret;
   @StringProperty(
      description = "Roles required to view technical clients (list with details). At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      optional = true,
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Technical Clients Management")
   private String viewTechnicalClients;
   @StringProperty(
      description = "Roles required to create and edit technical clients, its API keys and plans. Also allows to delete API keys and plans. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      displayName = "Create And Edit Technical Clients / API Keys / Plans",
      optional = true,
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Technical Clients Management")
   private String createEditTechnicalClient;
   @StringProperty(
      description = "Roles required to delete technical clients. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      displayName = "Delete Technical Clients",
      optional = true,
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Technical Clients Management")
   private String deleteTechnicalClient;
   @StringProperty(
      description = "Roles required to lock technical clients and API keys. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      displayName = "Lock Technical Clients / API Keys",
      optional = true,
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Technical Clients Management")
   private String lockTechnicalClient;
   @StringProperty(
      description = "Roles required to unlock technical clients and API keys. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      displayName = "Unlock Technical Clients / API Keys",
      optional = true,
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Technical Clients Management")
   private String unlockTechnicalClient;
   @StringProperty(
      displayName = "List Maintenance Messages",
      optional = true,
      description = "Roles required to list maintenance messages. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Maintenance Message Management")
   private String listMaintenanceMessages;
   @StringProperty(
      displayName = "Edit Maintenance Messages",
      optional = true,
      description = "Roles required to edit maintenance messages. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Maintenance Message Management")
   private String editMaintenanceMessage;
   @StringProperty(
      displayName = "Delete Maintenance Messages",
      optional = true,
      description = "Roles required to delete maintenance messages. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Maintenance Message Management")
   private String deleteMaintenanceMessage;
   @StringProperty(
      displayName = "List Administrators",
      optional = true,
      description = "Roles required to list administrators. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String listAdministrators;
   @StringProperty(
      displayName = "View Administrators",
      optional = true,
      description = "Roles required to view administrator details. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String viewAdministrator;
   @StringProperty(
      displayName = "Edit Administrators",
      optional = true,
      description = "<p>Roles required to edit administrators. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.</p><p><em>CAUTION</em>: Editing administrators includes assigning roles to administrators. Thus, an administrator with this privilege is able to assign this privilege also to other administrators.</p>",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String editAdministrator;
   @StringProperty(
      displayName = "Delete Administrators",
      optional = true,
      description = "Roles required to delete administrators. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String deleteAdministrator;
   @StringProperty(
      displayName = "Add New Administrators",
      optional = true,
      description = "Roles required to create administrators. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String createAdministrator;
   @StringProperty(
      displayName = "Lock Administrators",
      optional = true,
      description = "Roles required to lock administrators. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String lockAdministrator;
   @StringProperty(
      displayName = "Unlock Administrators",
      optional = true,
      description = "Roles required to unlock administrators. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String unlockAdministrator;
   @StringProperty(
      displayName = "Delete Administrator's Password",
      optional = true,
      description = "Roles required to delete administrators password. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String deleteAdministratorPassword;
   @StringProperty(
      displayName = "Change Administrator's Password",
      optional = true,
      description = "Roles required for an administrator to change his own password. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String changeAdministratorPassword;
   @StringProperty(
      displayName = "Generate Administrator Password",
      optional = true,
      description = "Roles required to generate administrators password. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Administrator Management")
   private String generateAdministratorPassword;
   @StringProperty(
      displayName = "Edit Configuration",
      optional = true,
      description = "Roles required to edit configurations. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Configuration Management")
   private String editConfig;
   @StringProperty(
      displayName = "Apply Configuration",
      optional = true,
      description = "<p>Roles required to apply configurations. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.</p><p><em>CAUTION</em>: Because administrator access control is also part of the configuration, an administrator with this privilege can possibly gain all possible administrator rights.</p>",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Configuration Management")
   private String applyConfig;
   @StringProperty(
      displayName = "View Log Files",
      optional = true,
      description = "Roles required to view log files. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Miscellaneous")
   private String viewLog;
   @StringProperty(
      displayName = "View License",
      optional = true,
      description = "Roles required to view and edit the license. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Miscellaneous")
   private String viewLicense;
   @StringProperty(
      displayName = "Access Service Container Management",
      optional = true,
      description = "Roles required to access the service container. At least one of the listed, comma-separated roles are sufficient. Without a value, access is always denied. The special value 'NO RESTRICTION' allows access for any authenticated admin, without role restrictions.",
      suggestedValues = {
            "NO RESTRICTION",
            "useradmin",
            "helpdesk",
            "useradmin,helpdesk",
            "useradmin,tokenadmin",
            "tokenadmin,helpdesk",
            "useradmin,tokenadmin,helpdesk,sysadmin,superadmin"
      }
   )
   @GroupProperty(groupIdentifier = "Miscellaneous")
   private String accessServiceContainer;
   private AccessController accessController;
   private boolean recoveryMode;

   public RoleBasedAccessControllerConfig(
      ResourceAccessController restServiceAccessController,
      String listUsers,
      String viewUser,
      String viewUserLogs,
      String viewContextData,
      List<ContextDataAccessRule> detailedViewContextData,
      String displayUserManagementExtensions,
      List<UserManagementExtensionAccessRuleConfig> detailedDisplayUserManagementExtensions,
      String editUser,
      List<ContextDataAccessRule> detailedEditContextData,
      String editUsername,
      String deleteUser,
      String createUser,
      String lockUser,
      String unlockUser,
      String manageOAuth2Consents,
      String orderPassword,
      String unorderPassword,
      String deletePassword,
      String generatePassword,
      String triggerPasswordReset,
      String viewToken,
      String editToken,
      String orderNewToken,
      String unorderNewToken,
      String deleteToken,
      String activateToken,
      String deactivateToken,
      String generateTokenIak,
      String manageTokens,
      String viewOathOtpTokenSecret,
      String viewAirlock2FAActivationSecret,
      String viewCrontoActivationSecret,
      String viewTechnicalClients,
      String createEditTechnicalClient,
      String deleteTechnicalClient,
      String lockTechnicalClient,
      String unlockTechnicalClient,
      String listMaintenanceMessages,
      String editMaintenanceMessage,
      String deleteMaintenanceMessage,
      String listAdministrators,
      String viewAdministrator,
      String editAdministrator,
      String deleteAdministrator,
      String createAdministrator,
      String lockAdministrator,
      String unlockAdministrator,
      String deleteAdministratorPassword,
      String changeAdministratorPassword,
      String generateAdministratorPassword,
      String editConfig,
      String applyConfig,
      String viewLog,
      String viewLicense,
      String accessServiceContainer
   ) {
      this.restServiceAccessController = restServiceAccessController;
      this.listUsers = listUsers;
      this.viewUser = viewUser;
      this.viewUserLogs = viewUserLogs;
      this.viewContextData = viewContextData;
      this.detailedViewContextData = detailedViewContextData;
      this.displayUserManagementExtensions = displayUserManagementExtensions;
      this.detailedDisplayUserManagementExtensions = detailedDisplayUserManagementExtensions;
      this.editUser = editUser;
      this.detailedEditContextData = detailedEditContextData;
      this.editUsername = editUsername;
      this.deleteUser = deleteUser;
      this.createUser = createUser;
      this.lockUser = lockUser;
      this.unlockUser = unlockUser;
      this.manageOAuth2Consents = manageOAuth2Consents;
      this.orderPassword = orderPassword;
      this.unorderPassword = unorderPassword;
      this.deletePassword = deletePassword;
      this.generatePassword = generatePassword;
      this.triggerPasswordReset = triggerPasswordReset;
      this.viewToken = viewToken;
      this.editToken = editToken;
      this.orderNewToken = orderNewToken;
      this.unorderNewToken = unorderNewToken;
      this.deleteToken = deleteToken;
      this.activateToken = activateToken;
      this.deactivateToken = deactivateToken;
      this.generateTokenIak = generateTokenIak;
      this.manageTokens = manageTokens;
      this.viewOathOtpTokenSecret = viewOathOtpTokenSecret;
      this.viewAirlock2FAActivationSecret = viewAirlock2FAActivationSecret;
      this.viewCrontoActivationSecret = viewCrontoActivationSecret;
      this.viewTechnicalClients = viewTechnicalClients;
      this.createEditTechnicalClient = createEditTechnicalClient;
      this.deleteTechnicalClient = deleteTechnicalClient;
      this.lockTechnicalClient = lockTechnicalClient;
      this.unlockTechnicalClient = unlockTechnicalClient;
      this.listMaintenanceMessages = listMaintenanceMessages;
      this.editMaintenanceMessage = editMaintenanceMessage;
      this.deleteMaintenanceMessage = deleteMaintenanceMessage;
      this.listAdministrators = listAdministrators;
      this.viewAdministrator = viewAdministrator;
      this.editAdministrator = editAdministrator;
      this.deleteAdministrator = deleteAdministrator;
      this.createAdministrator = createAdministrator;
      this.lockAdministrator = lockAdministrator;
      this.unlockAdministrator = unlockAdministrator;
      this.deleteAdministratorPassword = deleteAdministratorPassword;
      this.changeAdministratorPassword = changeAdministratorPassword;
      this.generateAdministratorPassword = generateAdministratorPassword;
      this.editConfig = editConfig;
      this.applyConfig = applyConfig;
      this.viewLog = viewLog;
      this.viewLicense = viewLicense;
      this.accessServiceContainer = accessServiceContainer;
   }

   @Override
   public void setRecoveryMode(boolean recoveryMode) {
      this.recoveryMode = recoveryMode;
      this.initializeAccessController();
   }

   @AfterConfigActivation
   void afterConfigActivation() {
      this.initializeAccessController();
   }

   private void initializeAccessController() {
      ResourceAccessController restAccessController = this.createRestAccessController();
      ActionBasedAccessController actionAccessController = this.createActionBasedAccessController();
      this.accessController = new CombiningAccessController(restAccessController, actionAccessController);
   }

   private ResourceAccessController createRestAccessController() {
      ActionsToRest actionsToRest = new ActionsToRest(this, this.recoveryMode);
      Map<String, List<ResourceAccessControllerAccessRule>> actionToRestMappings = actionsToRest.getMappings();
      ResourceAccessControllerBuilder resourceAccessController;
      if (!this.recoveryMode && this.restServiceAccessController != null) {
         resourceAccessController = this.restServiceAccessController.toBuilder();
      } else {
         resourceAccessController = PluginPropertyBuilderInitializer.builder(ResourceAccessControllerBuilder.class);
      }

      resourceAccessController.allowRule(this.allow(Pattern.compile("/adminapp"), "GET", "NO RESTRICTION"));
      resourceAccessController.allowRule(this.allow(Pattern.compile("/usage-data"), "GET", "NO RESTRICTION"));
      resourceAccessController.allowRule(this.allow(Pattern.compile("/adminapp/user-detail/?"), "GET", "NO RESTRICTION"));
      resourceAccessController.allowRule(this.allow(Pattern.compile("/adminapp/user-detail/[^/]+"), "GET", "NO RESTRICTION"));
      resourceAccessController.allowRule(this.allow(Pattern.compile("/adminapp/ui/tokens/generic/[^/]+"), "GET", "NO RESTRICTION"));
      resourceAccessController.allowRule(this.allow(Pattern.compile("/adminapp/validate-dynamic-urls"), "POST", "NO RESTRICTION"));
      resourceAccessController.allowRule(this.allow(Pattern.compile("/license/warnings/?"), "GET", "NO RESTRICTION"));
      actionToRestMappings.forEach((name, rules) -> rules.forEach(resourceAccessController::allowRule));
      return resourceAccessController.build();
   }

   private ResourceAccessControllerAccessRule allow(Pattern pathPattern, String methodPattern, String roles) {
      return PluginPropertyBuilderInitializer.builder(ResourceAccessControllerAccessRuleBuilder.class)
         .pathPattern(pathPattern)
         .methodPattern(methodPattern)
         .roles(roles)
         .build();
   }

   private ActionBasedAccessController createActionBasedAccessController() {
      Set<String> allowedActions = Actions.allowedActions(this.recoveryMode).stream().map(Enum::name).collect(Collectors.toSet());
      ActionBasedAccessController actionAccessController = new ActionBasedAccessController();
      Set<Field> fields = ReflectionHelper.getAllFieldsOfType(String.class, this.getClass());
      fields.stream()
         .filter(field -> allowedActions.contains(field.getName()))
         .forEach(field -> actionAccessController.addAction(field.getName(), ReflectionHelper.getStringValue(field, this, "")));
      if (allowedActions.contains(Actions.viewContextData.name())) {
         this.detailedViewContextData
            .forEach(
               rule -> actionAccessController.addAction(
                  ContextDataAccessRule.toAction(Actions.viewContextData, rule.getContextDataField()), rule.getRoles() == null ? "" : rule.getRoles()
               )
            );
      }

      if (allowedActions.contains(Actions.editUser.name())) {
         this.detailedEditContextData
            .forEach(
               rule -> actionAccessController.addAction(
                  ContextDataAccessRule.toAction(Actions.editUser, rule.getContextDataField()), rule.getRoles() == null ? "" : rule.getRoles()
               )
            );
      }

      if (allowedActions.contains(Actions.displayUserManagementExtensions.name())) {
         this.detailedDisplayUserManagementExtensions
            .forEach(
               rule -> actionAccessController.addAction(
                  UserManagementExtensionAccessRuleConfig.toAction(rule.getId()), rule.getRoles() == null ? "" : rule.getRoles()
               )
            );
      }

      return actionAccessController;
   }

   @Override
   public AccessController getAccessController() {
      return this.accessController;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder builder() {
      return new RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public RoleBasedAccessControllerConfig() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class RoleBasedAccessControllerConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ResourceAccessController restServiceAccessController;
      @SuppressFBWarnings(justification = "generated code")
      private String listUsers;
      @SuppressFBWarnings(justification = "generated code")
      private String viewUser;
      @SuppressFBWarnings(justification = "generated code")
      private String viewUserLogs;
      @SuppressFBWarnings(justification = "generated code")
      private String viewContextData;
      @SuppressFBWarnings(justification = "generated code")
      private List<ContextDataAccessRule> detailedViewContextData;
      @SuppressFBWarnings(justification = "generated code")
      private String displayUserManagementExtensions;
      @SuppressFBWarnings(justification = "generated code")
      private List<UserManagementExtensionAccessRuleConfig> detailedDisplayUserManagementExtensions;
      @SuppressFBWarnings(justification = "generated code")
      private String editUser;
      @SuppressFBWarnings(justification = "generated code")
      private List<ContextDataAccessRule> detailedEditContextData;
      @SuppressFBWarnings(justification = "generated code")
      private String editUsername;
      @SuppressFBWarnings(justification = "generated code")
      private String deleteUser;
      @SuppressFBWarnings(justification = "generated code")
      private String createUser;
      @SuppressFBWarnings(justification = "generated code")
      private String lockUser;
      @SuppressFBWarnings(justification = "generated code")
      private String unlockUser;
      @SuppressFBWarnings(justification = "generated code")
      private String manageOAuth2Consents;
      @SuppressFBWarnings(justification = "generated code")
      private String orderPassword;
      @SuppressFBWarnings(justification = "generated code")
      private String unorderPassword;
      @SuppressFBWarnings(justification = "generated code")
      private String deletePassword;
      @SuppressFBWarnings(justification = "generated code")
      private String generatePassword;
      @SuppressFBWarnings(justification = "generated code")
      private String triggerPasswordReset;
      @SuppressFBWarnings(justification = "generated code")
      private String viewToken;
      @SuppressFBWarnings(justification = "generated code")
      private String editToken;
      @SuppressFBWarnings(justification = "generated code")
      private String orderNewToken;
      @SuppressFBWarnings(justification = "generated code")
      private String unorderNewToken;
      @SuppressFBWarnings(justification = "generated code")
      private String deleteToken;
      @SuppressFBWarnings(justification = "generated code")
      private String activateToken;
      @SuppressFBWarnings(justification = "generated code")
      private String deactivateToken;
      @SuppressFBWarnings(justification = "generated code")
      private String generateTokenIak;
      @SuppressFBWarnings(justification = "generated code")
      private String manageTokens;
      @SuppressFBWarnings(justification = "generated code")
      private String viewOathOtpTokenSecret;
      @SuppressFBWarnings(justification = "generated code")
      private String viewAirlock2FAActivationSecret;
      @SuppressFBWarnings(justification = "generated code")
      private String viewCrontoActivationSecret;
      @SuppressFBWarnings(justification = "generated code")
      private String viewTechnicalClients;
      @SuppressFBWarnings(justification = "generated code")
      private String createEditTechnicalClient;
      @SuppressFBWarnings(justification = "generated code")
      private String deleteTechnicalClient;
      @SuppressFBWarnings(justification = "generated code")
      private String lockTechnicalClient;
      @SuppressFBWarnings(justification = "generated code")
      private String unlockTechnicalClient;
      @SuppressFBWarnings(justification = "generated code")
      private String listMaintenanceMessages;
      @SuppressFBWarnings(justification = "generated code")
      private String editMaintenanceMessage;
      @SuppressFBWarnings(justification = "generated code")
      private String deleteMaintenanceMessage;
      @SuppressFBWarnings(justification = "generated code")
      private String listAdministrators;
      @SuppressFBWarnings(justification = "generated code")
      private String viewAdministrator;
      @SuppressFBWarnings(justification = "generated code")
      private String editAdministrator;
      @SuppressFBWarnings(justification = "generated code")
      private String deleteAdministrator;
      @SuppressFBWarnings(justification = "generated code")
      private String createAdministrator;
      @SuppressFBWarnings(justification = "generated code")
      private String lockAdministrator;
      @SuppressFBWarnings(justification = "generated code")
      private String unlockAdministrator;
      @SuppressFBWarnings(justification = "generated code")
      private String deleteAdministratorPassword;
      @SuppressFBWarnings(justification = "generated code")
      private String changeAdministratorPassword;
      @SuppressFBWarnings(justification = "generated code")
      private String generateAdministratorPassword;
      @SuppressFBWarnings(justification = "generated code")
      private String editConfig;
      @SuppressFBWarnings(justification = "generated code")
      private String applyConfig;
      @SuppressFBWarnings(justification = "generated code")
      private String viewLog;
      @SuppressFBWarnings(justification = "generated code")
      private String viewLicense;
      @SuppressFBWarnings(justification = "generated code")
      private String accessServiceContainer;

      @SuppressFBWarnings(justification = "generated code")
      RoleBasedAccessControllerConfigBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder restServiceAccessController(
         ResourceAccessController restServiceAccessController
      ) {
         this.restServiceAccessController = restServiceAccessController;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder listUsers(String listUsers) {
         this.listUsers = listUsers;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewUser(String viewUser) {
         this.viewUser = viewUser;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewUserLogs(String viewUserLogs) {
         this.viewUserLogs = viewUserLogs;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewContextData(String viewContextData) {
         this.viewContextData = viewContextData;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder detailedViewContextData(List<ContextDataAccessRule> detailedViewContextData) {
         this.detailedViewContextData = detailedViewContextData;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder displayUserManagementExtensions(String displayUserManagementExtensions) {
         this.displayUserManagementExtensions = displayUserManagementExtensions;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder detailedDisplayUserManagementExtensions(
         List<UserManagementExtensionAccessRuleConfig> detailedDisplayUserManagementExtensions
      ) {
         this.detailedDisplayUserManagementExtensions = detailedDisplayUserManagementExtensions;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder editUser(String editUser) {
         this.editUser = editUser;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder detailedEditContextData(List<ContextDataAccessRule> detailedEditContextData) {
         this.detailedEditContextData = detailedEditContextData;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder editUsername(String editUsername) {
         this.editUsername = editUsername;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deleteUser(String deleteUser) {
         this.deleteUser = deleteUser;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder createUser(String createUser) {
         this.createUser = createUser;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder lockUser(String lockUser) {
         this.lockUser = lockUser;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder unlockUser(String unlockUser) {
         this.unlockUser = unlockUser;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder manageOAuth2Consents(String manageOAuth2Consents) {
         this.manageOAuth2Consents = manageOAuth2Consents;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder orderPassword(String orderPassword) {
         this.orderPassword = orderPassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder unorderPassword(String unorderPassword) {
         this.unorderPassword = unorderPassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deletePassword(String deletePassword) {
         this.deletePassword = deletePassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder generatePassword(String generatePassword) {
         this.generatePassword = generatePassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder triggerPasswordReset(String triggerPasswordReset) {
         this.triggerPasswordReset = triggerPasswordReset;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewToken(String viewToken) {
         this.viewToken = viewToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder editToken(String editToken) {
         this.editToken = editToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder orderNewToken(String orderNewToken) {
         this.orderNewToken = orderNewToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder unorderNewToken(String unorderNewToken) {
         this.unorderNewToken = unorderNewToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deleteToken(String deleteToken) {
         this.deleteToken = deleteToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder activateToken(String activateToken) {
         this.activateToken = activateToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deactivateToken(String deactivateToken) {
         this.deactivateToken = deactivateToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder generateTokenIak(String generateTokenIak) {
         this.generateTokenIak = generateTokenIak;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder manageTokens(String manageTokens) {
         this.manageTokens = manageTokens;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewOathOtpTokenSecret(String viewOathOtpTokenSecret) {
         this.viewOathOtpTokenSecret = viewOathOtpTokenSecret;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewAirlock2FAActivationSecret(String viewAirlock2FAActivationSecret) {
         this.viewAirlock2FAActivationSecret = viewAirlock2FAActivationSecret;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewCrontoActivationSecret(String viewCrontoActivationSecret) {
         this.viewCrontoActivationSecret = viewCrontoActivationSecret;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewTechnicalClients(String viewTechnicalClients) {
         this.viewTechnicalClients = viewTechnicalClients;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder createEditTechnicalClient(String createEditTechnicalClient) {
         this.createEditTechnicalClient = createEditTechnicalClient;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deleteTechnicalClient(String deleteTechnicalClient) {
         this.deleteTechnicalClient = deleteTechnicalClient;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder lockTechnicalClient(String lockTechnicalClient) {
         this.lockTechnicalClient = lockTechnicalClient;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder unlockTechnicalClient(String unlockTechnicalClient) {
         this.unlockTechnicalClient = unlockTechnicalClient;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder listMaintenanceMessages(String listMaintenanceMessages) {
         this.listMaintenanceMessages = listMaintenanceMessages;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder editMaintenanceMessage(String editMaintenanceMessage) {
         this.editMaintenanceMessage = editMaintenanceMessage;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deleteMaintenanceMessage(String deleteMaintenanceMessage) {
         this.deleteMaintenanceMessage = deleteMaintenanceMessage;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder listAdministrators(String listAdministrators) {
         this.listAdministrators = listAdministrators;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewAdministrator(String viewAdministrator) {
         this.viewAdministrator = viewAdministrator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder editAdministrator(String editAdministrator) {
         this.editAdministrator = editAdministrator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deleteAdministrator(String deleteAdministrator) {
         this.deleteAdministrator = deleteAdministrator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder createAdministrator(String createAdministrator) {
         this.createAdministrator = createAdministrator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder lockAdministrator(String lockAdministrator) {
         this.lockAdministrator = lockAdministrator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder unlockAdministrator(String unlockAdministrator) {
         this.unlockAdministrator = unlockAdministrator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder deleteAdministratorPassword(String deleteAdministratorPassword) {
         this.deleteAdministratorPassword = deleteAdministratorPassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder changeAdministratorPassword(String changeAdministratorPassword) {
         this.changeAdministratorPassword = changeAdministratorPassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder generateAdministratorPassword(String generateAdministratorPassword) {
         this.generateAdministratorPassword = generateAdministratorPassword;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder editConfig(String editConfig) {
         this.editConfig = editConfig;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder applyConfig(String applyConfig) {
         this.applyConfig = applyConfig;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewLog(String viewLog) {
         this.viewLog = viewLog;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder viewLicense(String viewLicense) {
         this.viewLicense = viewLicense;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder accessServiceContainer(String accessServiceContainer) {
         this.accessServiceContainer = accessServiceContainer;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public RoleBasedAccessControllerConfig build() {
         return new RoleBasedAccessControllerConfig(
            this.restServiceAccessController,
            this.listUsers,
            this.viewUser,
            this.viewUserLogs,
            this.viewContextData,
            this.detailedViewContextData,
            this.displayUserManagementExtensions,
            this.detailedDisplayUserManagementExtensions,
            this.editUser,
            this.detailedEditContextData,
            this.editUsername,
            this.deleteUser,
            this.createUser,
            this.lockUser,
            this.unlockUser,
            this.manageOAuth2Consents,
            this.orderPassword,
            this.unorderPassword,
            this.deletePassword,
            this.generatePassword,
            this.triggerPasswordReset,
            this.viewToken,
            this.editToken,
            this.orderNewToken,
            this.unorderNewToken,
            this.deleteToken,
            this.activateToken,
            this.deactivateToken,
            this.generateTokenIak,
            this.manageTokens,
            this.viewOathOtpTokenSecret,
            this.viewAirlock2FAActivationSecret,
            this.viewCrontoActivationSecret,
            this.viewTechnicalClients,
            this.createEditTechnicalClient,
            this.deleteTechnicalClient,
            this.lockTechnicalClient,
            this.unlockTechnicalClient,
            this.listMaintenanceMessages,
            this.editMaintenanceMessage,
            this.deleteMaintenanceMessage,
            this.listAdministrators,
            this.viewAdministrator,
            this.editAdministrator,
            this.deleteAdministrator,
            this.createAdministrator,
            this.lockAdministrator,
            this.unlockAdministrator,
            this.deleteAdministratorPassword,
            this.changeAdministratorPassword,
            this.generateAdministratorPassword,
            this.editConfig,
            this.applyConfig,
            this.viewLog,
            this.viewLicense,
            this.accessServiceContainer
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "RoleBasedAccessControllerConfig.RoleBasedAccessControllerConfigBuilder(restServiceAccessController="
            + this.restServiceAccessController
            + ", listUsers="
            + this.listUsers
            + ", viewUser="
            + this.viewUser
            + ", viewUserLogs="
            + this.viewUserLogs
            + ", viewContextData="
            + this.viewContextData
            + ", detailedViewContextData="
            + this.detailedViewContextData
            + ", displayUserManagementExtensions="
            + this.displayUserManagementExtensions
            + ", detailedDisplayUserManagementExtensions="
            + this.detailedDisplayUserManagementExtensions
            + ", editUser="
            + this.editUser
            + ", detailedEditContextData="
            + this.detailedEditContextData
            + ", editUsername="
            + this.editUsername
            + ", deleteUser="
            + this.deleteUser
            + ", createUser="
            + this.createUser
            + ", lockUser="
            + this.lockUser
            + ", unlockUser="
            + this.unlockUser
            + ", manageOAuth2Consents="
            + this.manageOAuth2Consents
            + ", orderPassword="
            + this.orderPassword
            + ", unorderPassword="
            + this.unorderPassword
            + ", deletePassword="
            + this.deletePassword
            + ", generatePassword="
            + this.generatePassword
            + ", triggerPasswordReset="
            + this.triggerPasswordReset
            + ", viewToken="
            + this.viewToken
            + ", editToken="
            + this.editToken
            + ", orderNewToken="
            + this.orderNewToken
            + ", unorderNewToken="
            + this.unorderNewToken
            + ", deleteToken="
            + this.deleteToken
            + ", activateToken="
            + this.activateToken
            + ", deactivateToken="
            + this.deactivateToken
            + ", generateTokenIak="
            + this.generateTokenIak
            + ", manageTokens="
            + this.manageTokens
            + ", viewOathOtpTokenSecret="
            + this.viewOathOtpTokenSecret
            + ", viewAirlock2FAActivationSecret="
            + this.viewAirlock2FAActivationSecret
            + ", viewCrontoActivationSecret="
            + this.viewCrontoActivationSecret
            + ", viewTechnicalClients="
            + this.viewTechnicalClients
            + ", createEditTechnicalClient="
            + this.createEditTechnicalClient
            + ", deleteTechnicalClient="
            + this.deleteTechnicalClient
            + ", lockTechnicalClient="
            + this.lockTechnicalClient
            + ", unlockTechnicalClient="
            + this.unlockTechnicalClient
            + ", listMaintenanceMessages="
            + this.listMaintenanceMessages
            + ", editMaintenanceMessage="
            + this.editMaintenanceMessage
            + ", deleteMaintenanceMessage="
            + this.deleteMaintenanceMessage
            + ", listAdministrators="
            + this.listAdministrators
            + ", viewAdministrator="
            + this.viewAdministrator
            + ", editAdministrator="
            + this.editAdministrator
            + ", deleteAdministrator="
            + this.deleteAdministrator
            + ", createAdministrator="
            + this.createAdministrator
            + ", lockAdministrator="
            + this.lockAdministrator
            + ", unlockAdministrator="
            + this.unlockAdministrator
            + ", deleteAdministratorPassword="
            + this.deleteAdministratorPassword
            + ", changeAdministratorPassword="
            + this.changeAdministratorPassword
            + ", generateAdministratorPassword="
            + this.generateAdministratorPassword
            + ", editConfig="
            + this.editConfig
            + ", applyConfig="
            + this.applyConfig
            + ", viewLog="
            + this.viewLog
            + ", viewLicense="
            + this.viewLicense
            + ", accessServiceContainer="
            + this.accessServiceContainer
            + ")";
      }
   }
}
