/// <summary>
        /// Initializes a new instance of the <see cref="EdFiAuthorizationProvider"/> class using the specified
        /// authorization strategy provider.
        /// </summary>
        /// <param name="resourceAuthorizationMetadataProvider">The component that will be used to supply the claims/strategies that can be used to authorize the resource.</param>
        /// <param name="authorizationStrategies"></param>
        /// <param name="securityRepository"></param>
        /// <param name="explicitObjectValidators"></param>
        public EdFiAuthorizationProvider(
            IResourceAuthorizationMetadataProvider resourceAuthorizationMetadataProvider,
            IEdFiAuthorizationStrategy[] authorizationStrategies,
            ISecurityRepository securityRepository,
            IExplicitObjectValidator[] explicitObjectValidators)
        {
            if (resourceAuthorizationMetadataProvider == null)
            {
                throw new ArgumentNullException("resourceAuthorizationMetadataProvider");
            }

            if (securityRepository == null)
            {
                throw new ArgumentNullException("securityRepository");
            }

            _resourceAuthorizationMetadataProvider = resourceAuthorizationMetadataProvider;
            _securityRepository       = securityRepository;
            _explicitObjectValidators = explicitObjectValidators;

            _authorizationStrategyByName = CreateAuthorizationStrategyByNameDictionary(authorizationStrategies);

            // Lazy initialization
            _bitValuesByAction = new Lazy <Dictionary <string, int> >(
                () => new Dictionary <string, int>
            {
                {
                    _securityRepository.GetActionByName("Create")
                    .ActionUri,
                    0x1
                },
                {
                    _securityRepository.GetActionByName("Read")
                    .ActionUri,
                    0x2
                },
                {
                    _securityRepository.GetActionByName("Update")
                    .ActionUri,
                    0x4
                },
                {
                    _securityRepository.GetActionByName("Delete")
                    .ActionUri,
                    0x8
                }
            });
        }
    /// <summary>
    /// Initializes a new instance of the <see cref="AuthorizationBasisMetadataSelector"/> class.
    /// </summary>
    /// <param name="resourceAuthorizationMetadataProvider">The component that will be used to supply the claims/strategies that can be used to authorize the resource.</param>
    /// <param name="securityRepository"></param>
    /// <param name="authorizationStrategies"></param>
    public AuthorizationBasisMetadataSelector(
        IResourceAuthorizationMetadataProvider resourceAuthorizationMetadataProvider,
        ISecurityRepository securityRepository,
        IAuthorizationStrategy[] authorizationStrategies)
    {
        _resourceAuthorizationMetadataProvider = resourceAuthorizationMetadataProvider;

        // Lazy initialization
        _bitValuesByAction = new Lazy <Dictionary <string, int> >(
            () => new Dictionary <string, int>
        {
            { securityRepository.GetActionByName("Create").ActionUri, 0x1 },
            { securityRepository.GetActionByName("Read").ActionUri, 0x2 },
            { securityRepository.GetActionByName("Update").ActionUri, 0x4 },
            { securityRepository.GetActionByName("Delete").ActionUri, 0x8 }
        });

        _authorizationStrategyByName = CreateAuthorizationStrategyByNameDictionary(authorizationStrategies);

        Dictionary <string, IAuthorizationStrategy> CreateAuthorizationStrategyByNameDictionary(
            IAuthorizationStrategy[] authorizationStrategies)
        {
            var strategyByName = new Dictionary <string, IAuthorizationStrategy>(
                StringComparer.InvariantCultureIgnoreCase);

            foreach (var strategy in authorizationStrategies)
            {
                string strategyTypeName = GetStrategyTypeName(strategy);

                const string authorizationStrategyNameSuffix = "AuthorizationStrategy";

                // TODO: Embedded convention
                // Enforce naming conventions on authorization strategies
                if (!strategyTypeName.EndsWith(authorizationStrategyNameSuffix))
                {
                    throw new ArgumentException(
                              string.Format(
                                  "The authorization strategy '{0}' does not follow proper naming conventions, ending with 'AuthorizationStrategy'.",
                                  strategyTypeName));
                }

                string strategyName = strategyTypeName.TrimSuffix(authorizationStrategyNameSuffix);
                strategyByName.Add(strategyName, strategy);
            }

            return(strategyByName);
        }

        string GetStrategyTypeName(IAuthorizationStrategy strategy)
        {
            string rawTypeName = strategy.GetType().Name;

            int genericMarkerPos = rawTypeName.IndexOf("`");

            string strategyTypeName = genericMarkerPos < 0
                ? rawTypeName
                : rawTypeName.Substring(0, genericMarkerPos);

            return(strategyTypeName);
        }
    }