/// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
        /// <exception cref="T:System.ArgumentNullException">The name of the provider is null.</exception>
        /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>
        /// <exception cref="T:System.InvalidOperationException">An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"/> on a provider after the provider has already been initialized.</exception>
        public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);

            try
            {
                Error.AssertLicense("Sitecore.MSCRM", "Microsoft Dynamics CRM security provider.");

                this.ApplicationName = config["applicationName"];
                this.ReadOnly        = (String.IsNullOrEmpty(config["readOnly"]) || config["readOnly"] == "true");

                var connectionStringName = config["connectionStringName"];
                var connectionString     = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;

                var settings = Configuration.ConfigurationSettings.Parse(connectionString);

                this.profileRepository = this.profileRepositoryFactory.GetRepository(settings);
                this.userRepository    = this.userRepositoryFactory.GetRepository(settings);

                this.SetupCustomPropertyNames();

                this.initialized = true;
            }
            catch (Exception e)
            {
                this.initialized = false;
                ConditionalLog.Error("The CRM provider couldn't be initialized.", e, this);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CrmMembershipProviderTest"/> class.
        /// </summary>
        public CrmMembershipProviderTest()
        {
            var cacheService = Substitute.For <ICacheService>();

            this.userRepository    = Substitute.For <UserRepositoryBase>(cacheService);
            this.profileRepository = Substitute.For <ProfileRepositoryBase>(this.userRepository, cacheService);

            this.userRepositoryFactory = Substitute.For <IUserRepositoryFactory>();
            this.userRepositoryFactory.GetRepository(Arg.Any <ConfigurationSettings>()).Returns(this.userRepository);

            this.profileRepositoryFactory = Substitute.For <IProfileRepositoryFactory>();
            this.profileRepositoryFactory.GetRepository(Arg.Any <ConfigurationSettings>()).Returns(this.profileRepository);

            var config = new NameValueCollection();

            config.Add("name", "crm");
            config.Add("applicationName", "CRM security provider");
            config.Add("readOnly", "false");
            config.Add("connectionStringName", "CRMConnString");

            this.crmMembershipProvider = new CRMMembershipProvider(this.userRepositoryFactory, this.profileRepositoryFactory);
            this.crmMembershipProvider.Initialize(config["name"], config);

            this.user = new CRMUser(
                "*****@*****.**",
                Guid.NewGuid(),
                "*****@*****.**",
                null,
                String.Empty,
                true,
                false,
                DateTime.Now,
                DateTime.Now,
                DateTime.MinValue,
                DateTime.MinValue,
                DateTime.MinValue);
        }
        /// <summary>
        /// Initializes the provider.
        /// </summary>
        /// <param name="name">The friendly name of the provider.</param>
        /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
        /// <exception cref="T:System.ArgumentNullException">The name of the provider is null.</exception>
        /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>
        /// <exception cref="T:System.InvalidOperationException">An attempt is made to call <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"/> on a provider after the provider has already been initialized.</exception>
        public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);

            try
            {
                Error.AssertLicense("Sitecore.MSCRM", "Microsoft Dynamics CRM security provider.");

                this.ApplicationName                      = config["applicationName"];
                this.ReadOnly                             = (String.IsNullOrEmpty(config["readOnly"]) || config["readOnly"] == "true");
                this.AutoCreatePasswordField              = MainUtil.GetBool(config["autoCreatePasswordField"], false);
                this.PasswordFieldName                    = StringUtil.GetString((object)config["passwordFieldName"]);
                this.minRequiredPasswordLength            = MainUtil.GetInt(config["minRequiredPasswordLength"], 7);
                this.minRequiredNonalphanumericCharacters = MainUtil.GetInt(config["minRequiredNonalphanumericCharacters"], 1);
                this.maxInvalidPasswordAttempts           = MainUtil.GetInt(config["maxInvalidPasswordAttempts"], 5);
                this.passwordAttemptWindow                = MainUtil.GetInt(config["passwordAttemptWindow"], 0);
                this.passwordStrengthRegularExpression    = StringUtil.GetString((object)config["passwordStrengthRegularExpression"]).Trim();
                this.requiresUniqueEmail                  = MainUtil.GetBool(config["requiresUniqueEmail"], false);
                this.enablePasswordReset                  = MainUtil.GetBool(config["enablePasswordReset"], true);
                this.requiresQuestionAndAnswer            = MainUtil.GetBool(config["requiresQuestionAndAnswer"], false);
                if (this.RequiresQuestionAndAnswer)
                {
                    this.PasswordQuestionFieldName = config["passwordQuestionFieldName"];
                    this.PasswordAnswerFieldName   = config["passwordAnswerFieldName"];
                }

                if (!String.IsNullOrEmpty(this.passwordStrengthRegularExpression))
                {
                    new Regex(this.passwordStrengthRegularExpression);
                }

                var connectionStringName = config["connectionStringName"];
                var connectionString     = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;

                var settings = Configuration.ConfigurationSettings.Parse(connectionString);

                this.userRepository    = this.userRepositoryFactory.GetRepository(settings);
                this.profileRepository = this.profileRepositoryFactory.GetRepository(settings);
                this.initialized       = true;
            }
            catch (Exception e)
            {
                this.initialized = false;
                ConditionalLog.Error("The CRM provider couldn't be initialized.", e, this);

                return;
            }

            try
            {
                if (!String.IsNullOrEmpty(this.PasswordFieldName))
                {
                    var passwordFieldType = this.profileRepository.GetPropertyType(this.PasswordFieldName);
                    if (passwordFieldType != SupportedTypes.String)
                    {
                        this.PasswordFieldName = String.Empty;
                        ConditionalLog.Warn("The attribute for the password storage isn't of String type. Password storage feature disabled.", this);
                    }
                }
            }
            catch (ProviderException)
            {
                if ((this.userRepository is UserRepositoryV4 || this.userRepository is UserRepositoryV5) && this.AutoCreatePasswordField)
                {
                    if (!this.profileRepository.CreateContactAttribute(this.PasswordFieldName, SupportedTypes.String, false))
                    {
                        this.PasswordFieldName = String.Empty;
                        ConditionalLog.Warn("The attribute for password storage couldn't be created. Password storage feature disabled.", this);
                    }
                }
                else
                {
                    this.PasswordFieldName = String.Empty;
                    ConditionalLog.Warn("The attribute for the password storage doesn't exist. Password storage feature disabled.", this);
                }
            }
        }