public EntityAccessRuleSet Map <TAccessRule>(IEntityAccessRestrictable <TAccessRule> entity)
            where TAccessRule : IEntityAccessRule
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }
            MissingIncludeException.ThrowIfNull(entity, e => e.AccessRules);

            if (!entity.AccessRules.Any())
            {
                // no rules, so return null rather than an empty ruleset
                return(null);
            }

            var violationAction = EnumParser.ParseOrNull <AccessRuleViolationAction>(entity.AccessRuleViolationActionId);

            if (violationAction == null)
            {
                _logger.LogWarning(
                    "AccessRuleViolationAction of value {AccessRuleViolationAction} could not be parsed on rule type {TAccessRule}.",
                    entity.AccessRuleViolationActionId,
                    typeof(TAccessRule).Name
                    );
            }


            var result = new EntityAccessRuleSet()
            {
                ViolationAction = violationAction ?? AccessRuleViolationAction.Error
            };

            if (!string.IsNullOrWhiteSpace(entity.UserAreaCodeForSignInRedirect))
            {
                var userArea = _userAreaDefinitionRepository.GetRequiredByCode(entity.UserAreaCodeForSignInRedirect);
                result.UserAreaCodeForSignInRedirect = userArea.UserAreaCode;
            }

            result.AccessRules = entity
                                 .AccessRules
                                 .OrderByDefault()
                                 .Select(r => MapAccessRule(r))
                                 .ToArray();

            return(result);
        }
        private void EnforceRuleViolation(Controller controller, PageActionRoutingState state, EntityAccessRuleSet accessRuleViolation)
        {
            if (!state.AmbientUserContext.IsSignedIn() && accessRuleViolation.ShouldTryRedirect())
            {
                _logger.LogDebug("User not authenticated, redirecting to sign in page for user area {UserAreaCodeForLoginRedirect}.", accessRuleViolation.UserAreaCodeForSignInRedirect);
                var challengeScheme = AuthenticationSchemeNames.UserArea(accessRuleViolation.UserAreaCodeForSignInRedirect);
                state.Result = new ChallengeResult(challengeScheme);
                return;
            }

            _logger.LogDebug("Processing violation action {ViolationAction}.", accessRuleViolation.ViolationAction);
            switch (accessRuleViolation.ViolationAction)
            {
            case AccessRuleViolationAction.NotFound:
                // Set the route to null and the IGetNotFoundRouteRoutingStep will figure out the correct result
                state.PageRoutingInfo = null;
                break;

            case AccessRuleViolationAction.Error:
                // Throw an exception, which should be picked up by the global handler and dealt with accordingly.
                throw new AccessRuleViolationException($"User is not permitted to access {state.InputParameters.Path}.");

            default:
                throw new NotImplementedException($"{nameof(AccessRuleViolationAction)}.{accessRuleViolation.ViolationAction} not implemented.");
            }
            ;
        }