/// <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.InvalidOperationException">An attempt is made to call 
        /// <see cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"></see> on a provider after the provider 
        /// has already been initialized.</exception>
        /// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>       
        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null) {throw new ArgumentNullException("config");}

            if (string.IsNullOrEmpty(name)) name = ProviderName;

            // Initialize base provider class
            base.Initialize(name, config);

            _applicationName = string.IsNullOrEmpty(config["applicationName"]) ? GetDefaultAppName() : config["applicationName"];

            _enablePasswordRetrieval = GetBooleanValue(config, "enablePasswordRetrieval", false);
            _enablePasswordReset = GetBooleanValue(config, "enablePasswordReset", false);
            _requiresQuestionAndAnswer = GetBooleanValue(config, "requiresQuestionAndAnswer", false);
            _requiresUniqueEmail = GetBooleanValue(config, "requiresUniqueEmail", true);
            _maxInvalidPasswordAttempts = GetIntValue(config, "maxInvalidPasswordAttempts", 5, false, 0);
            _passwordAttemptWindow = GetIntValue(config, "passwordAttemptWindow", 10, false, 0);
            _minRequiredPasswordLength = GetIntValue(config, "minRequiredPasswordLength", 7, true, 0x80);
            _minRequiredNonAlphanumericCharacters = GetIntValue(config, "minRequiredNonalphanumericCharacters", 1, true, 0x80);
            _passwordStrengthRegularExpression = config["passwordStrengthRegularExpression"];

            // make sure password format is Hashed by default.
            var str = config["passwordFormat"] ?? "Hashed";

            LogHelper.Debug<MembersMembershipProvider>("Loaded membership provider properties");
            LogHelper.Debug<MembersMembershipProvider>(ToString());

            switch (str.ToLower())
            {
                case "clear":
                    _passwordFormat = MembershipPasswordFormat.Clear;
                    break;
                case "encrypted":
                    _passwordFormat = MembershipPasswordFormat.Encrypted;
                    break;
                case "hashed":
                    _passwordFormat = MembershipPasswordFormat.Hashed;
                    break;
                default:
                    var e = new ProviderException("Provider bad password format");
                    LogHelper.Error<MembersMembershipProvider>(e.Message, e);
                    throw e;
            }

            if ((PasswordFormat == MembershipPasswordFormat.Hashed) && EnablePasswordRetrieval)
            {
                var e = new ProviderException("Provider can not retrieve hashed password");
                LogHelper.Error<MembersMembershipProvider>(e.Message, e);
                throw e;
            }

            // TODO: rationalise what happens when no member alias is specified....
            DefaultMemberTypeAlias = config["defaultMemberTypeAlias"];
            
            LogHelper.Debug<MembersMembershipProvider>("Finished initialising member ship provider " + GetType().FullName);
        }
        private static void InitializeDefaultProvider(RoleManagerSection settings) {
            bool canInitializeDefaultProvider = (!HostingEnvironment.IsHosted || BuildManager.PreStartInitStage == PreStartInitStage.AfterPreStartInit);
            if (!s_InitializedDefaultProvider && canInitializeDefaultProvider) {
                Debug.Assert(s_Providers != null);
                s_Providers.SetReadOnly();

                if (settings.DefaultProvider == null) {
                    s_InitializeException = new ProviderException(SR.GetString(SR.Def_role_provider_not_specified));
                }
                else {
                    try {
                        s_Provider = s_Providers[settings.DefaultProvider];
                    }
                    catch { }
                }

                if (s_Provider == null) {
                    s_InitializeException = new ConfigurationErrorsException(SR.GetString(SR.Def_role_provider_not_found), settings.ElementInformation.Properties["defaultProvider"].Source, settings.ElementInformation.Properties["defaultProvider"].LineNumber);
                }

                s_InitializedDefaultProvider = true;
            }
        }
        public override void UpdateUser(MembershipUser user)
        {
            if (user == null) {
                throw TraceException("UpdateUser", new ArgumentNullException("user"));
            }

            var id = ConvertProviderUserKeyToObjectId(user.ProviderUserKey);
            if (!id.HasValue) {
                var message = ProviderResources.UserDoesNotExist;
                throw TraceException("UpdateUser", new ProviderException(message));
            }

            if (RequiresUniqueEmail && EmailIsDuplicate(user.Email)) {
                var message = ProviderResources.UserHasADuplicateEmailAddress;
                throw TraceException("UpdateUser", new ProviderException(message));
            }

            var query = Query.EQ("_id", id.Value);
            var update = Update
                .Set("UserName", user.UserName)
                .Set("Email", user.Email)
                .Set("Comment", user.Comment)
                .Set("IsApproved", user.IsApproved)
                .Set("LastLoginDate", SerializationHelper.SerializeDateTime(user.LastLoginDate))
                .Set("LastActivityDate", SerializationHelper.SerializeDateTime(user.LastActivityDate));

            try {
                var users = GetUserCollection();
                var result = users.Update(query, update);
                if (result.DocumentsAffected == 0) {
                    var providerException = new ProviderException(ProviderResources.UserDoesNotExist);
                    TraceException("UpdateUser", providerException);
                    throw providerException;
                }
            } catch (MongoSafeModeException e) {
                string message;
                if (e.Message.Contains("UserName_1")) {
                    message = ProviderResources.UserHasADuplicateName;
                } else {
                    message = ProviderResources.CouldNotUpdateUser;
                }
                throw TraceException("UpdateUser", new ProviderException(message, e));
            }
        }