public override void Initialize(string name, NameValueCollection config)
        {
            // Verify that config isn't null
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            // Assign the provider a default name if it doesn't have one
            if (String.IsNullOrEmpty(name))
            {
                name = "TableServiceSessionStateProvider";
            }

            // Add a default "description" attribute to config if the
            // attribute doesn't exist or is empty
            if (string.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "Session state provider using table storage");
            }

            // Call the base class's Initialize method
            base.Initialize(name, config);

            bool allowInsecureRemoteEndpoints = Configuration.GetBooleanValue(config, "allowInsecureRemoteEndpoints", false);

            // structure storage-related properties
            _applicationName = Configuration.GetStringValueWithGlobalDefault(config, "applicationName",
                                                                             Configuration.DefaultProviderApplicationNameConfigurationString,
                                                                             Configuration.DefaultProviderApplicationName, false);
            _accountName = Configuration.GetStringValue(config, "accountName", null, true);
            _sharedKey   = Configuration.GetStringValue(config, "sharedKey", null, true);
            _tableName   = Configuration.GetStringValueWithGlobalDefault(config, "sessionTableName",
                                                                         Configuration.DefaultSessionTableNameConfigurationString,
                                                                         Configuration.DefaultSessionTableName, false);
            _tableServiceBaseUri = Configuration.GetStringValue(config, "tableServiceBaseUri", null, true);
            _containerName       = Configuration.GetStringValueWithGlobalDefault(config, "containerName",
                                                                                 Configuration.DefaultSessionContainerNameConfigurationString,
                                                                                 Configuration.DefaultSessionContainerName, false);
            if (!SecUtility.IsValidContainerName(_containerName))
            {
                throw new ProviderException("The provider configuration for the TableStorageSessionStateProvider does not contain a valid container name. " +
                                            "Please refer to the documentation for the concrete rules for valid container names." +
                                            "The current container name is: " + _containerName);
            }
            _blobServiceBaseUri = Configuration.GetStringValue(config, "blobServiceBaseUri", null, true);

            config.Remove("allowInsecureRemoteEndpoints");
            config.Remove("accountName");
            config.Remove("sharedKey");
            config.Remove("containerName");
            config.Remove("applicationName");
            config.Remove("blobServiceBaseUri");
            config.Remove("tableServiceBaseUri");
            config.Remove("sessionTableName");

            // Throw an exception if unrecognized attributes remain
            if (config.Count > 0)
            {
                string attr = config.GetKey(0);
                if (!String.IsNullOrEmpty(attr))
                {
                    throw new ProviderException
                              ("Unrecognized attribute: " + attr);
                }
            }

            //StorageCredentialsAccountAndKey tableInfo = null;
            //StorageCredentialsAccountAndKey blobInfo = null;
            string tableBaseUri = null;
            string blobBaseUri  = null;

            try
            {
                var sharedKey   = Configuration.TryGetAppSetting(Configuration.DefaultAccountSharedKeyConfigurationString);
                var accountName = Configuration.TryGetAppSetting(Configuration.DefaultAccountNameConfigurationString);

                tableBaseUri = Configuration.TryGetAppSetting(Configuration.DefaultTableStorageEndpointConfigurationString);
                blobBaseUri  = Configuration.TryGetAppSetting(Configuration.DefaultBlobStorageEndpointConfigurationString);

                if (_tableServiceBaseUri != null)
                {
                    tableBaseUri = _tableServiceBaseUri;
                }
                if (_blobServiceBaseUri != null)
                {
                    blobBaseUri = _blobServiceBaseUri;
                }
                if (_accountName != null)
                {
                    accountName = _accountName;
                }
                if (_sharedKey != null)
                {
                    sharedKey = _sharedKey;
                }

                if (String.IsNullOrEmpty(sharedKey) || String.IsNullOrEmpty(accountName) || String.IsNullOrEmpty(tableBaseUri) || String.IsNullOrEmpty(blobBaseUri))
                {
                    throw new ConfigurationErrorsException("Account information incomplete!");
                }

                //tableInfo = new StorageCredentialsAccountAndKey(accountName, sharedKey);
                //blobInfo = new StorageCredentialsAccountAndKey(accountName, sharedKey);
                //SecUtility.CheckAllowInsecureEndpoints(allowInsecureRemoteEndpoints, tableInfo, new Uri(tableBaseUri));
                //SecUtility.CheckAllowInsecureEndpoints(allowInsecureRemoteEndpoints, blobInfo, new Uri(blobBaseUri));
                _tableStorage = new sqlTableClient(tableBaseUri);//, tableInfo);
                //_tableStorage.RetryPolicy = _tableRetry;
                if (_tableStorage.CreateTableIfNotExist(_tableName))
                {
                    var ctx      = _tableStorage.GetDataServiceContext();
                    var dummyRow = new SessionRow("fake", "dummy");
                    ctx.AddObject(_tableName, dummyRow);
                    ctx.SaveChangesWithRetries();
                    ctx.DeleteObject(dummyRow);
                    ctx.SaveChangesWithRetries();
                }
                //_blobProvider = new BlobProvider(blobInfo, new Uri(blobBaseUri), _containerName);
                _blobProvider = new BlobProvider(new Uri(blobBaseUri), _containerName);
            }
            catch (SecurityException)
            {
                throw;
            }
            // catch InvalidOperationException as well as StorageException
            catch (Exception e)
            {
                //string exceptionDescription = Configuration.GetInitExceptionDescription(tableInfo, new Uri(tableBaseUri), blobInfo, new Uri(blobBaseUri));
                string exceptionDescription = Configuration.GetInitExceptionDescription(new Uri(tableBaseUri), new Uri(blobBaseUri));
                string tableName            = (_tableName == null) ? "no session table name specified" : _tableName;
                string containerName        = (_containerName == null) ? "no container name specified" : _containerName;
                Log.Write(EventKind.Error, "Initialization of data service structures (tables and/or blobs) failed!" +
                          exceptionDescription + Environment.NewLine +
                          "Configured blob container: " + containerName + Environment.NewLine +
                          "Configured table name: " + tableName + Environment.NewLine +
                          e.Message + Environment.NewLine + e.StackTrace);
                throw new ProviderException("Initialization of data service structures (tables and/or blobs) failed!" +
                                            "The most probable reason for this is that " +
                                            "the storage endpoints are not configured correctly. Please look at the configuration settings " +
                                            "in your .cscfg and Web.config files. More information about this error " +
                                            "can be found in the logs when running inside the hosting environment or in the output " +
                                            "window of Visual Studio.", e);
            }
            Debug.Assert(_blobProvider != null);
        }
        // RoleProvider methods
        public override void Initialize(string name, NameValueCollection config)
        {
            // Verify that config isn't null
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            // Assign the provider a default name if it doesn't have one
            if (String.IsNullOrEmpty(name))
            {
                name = "TableStorageRoleProvider";
            }

            // Add a default "description" attribute to config if the
            // attribute doesn't exist or is empty
            if (string.IsNullOrEmpty(config["description"]))
            {
                config.Remove("description");
                config.Add("description", "Table storage-based role provider");
            }

            // Call the base class's Initialize method
            base.Initialize(name, config);

            bool allowInsecureRemoteEndpoints = Configuration.GetBooleanValue(config, "allowInsecureRemoteEndpoints", false);

            // structure storage-related properties
            ApplicationName = Configuration.GetStringValueWithGlobalDefault(config, "applicationName",
                                                                            Configuration.DefaultProviderApplicationNameConfigurationString,
                                                                            Configuration.DefaultProviderApplicationName, false);
            _accountName = Configuration.GetStringValue(config, "accountName", null, true);
            _sharedKey   = Configuration.GetStringValue(config, "sharedKey", null, true);
            _tableName   = Configuration.GetStringValueWithGlobalDefault(config, "roleTableName",
                                                                         Configuration.DefaultRoleTableNameConfigurationString,
                                                                         Configuration.DefaultRoleTableName, false);
            _membershipTableName = Configuration.GetStringValueWithGlobalDefault(config, "membershipTableName",
                                                                                 Configuration.DefaultMembershipTableNameConfigurationString,
                                                                                 Configuration.DefaultMembershipTableName, false);
            _tableServiceBaseUri = Configuration.GetStringValue(config, "tableServiceBaseUri", null, true);

            // remove required attributes
            config.Remove("allowInsecureRemoteEndpoints");
            config.Remove("applicationName");
            config.Remove("accountName");
            config.Remove("sharedKey");
            config.Remove("roleTableName");
            config.Remove("membershipTableName");
            config.Remove("tableServiceBaseUri");


            // Throw an exception if unrecognized attributes remain
            if (config.Count > 0)
            {
                string attr = config.GetKey(0);
                if (!String.IsNullOrEmpty(attr))
                {
                    throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Unrecognized attribute: {0}", attr));
                }
            }

            //StorageCredentialsAccountAndKey info = null;
            string baseUri = null;

            try
            {
                var sharedKey   = Configuration.TryGetAppSetting(Configuration.DefaultAccountSharedKeyConfigurationString);
                var accountName = Configuration.TryGetAppSetting(Configuration.DefaultAccountNameConfigurationString);

                baseUri = Configuration.TryGetAppSetting(Configuration.DefaultTableStorageEndpointConfigurationString);

                if (_tableServiceBaseUri != null)
                {
                    baseUri = _tableServiceBaseUri;
                }
                if (_accountName != null)
                {
                    accountName = _accountName;
                }
                if (_sharedKey != null)
                {
                    sharedKey = _sharedKey;
                }

                if (String.IsNullOrEmpty(sharedKey) || String.IsNullOrEmpty(accountName) || String.IsNullOrEmpty(baseUri))
                {
                    throw new ConfigurationErrorsException("Account information incomplete!");
                }

                //info = new StorageCredentialsAccountAndKey(accountName, sharedKey);
                //SecUtility.CheckAllowInsecureEndpoints(allowInsecureRemoteEndpoints, info, new Uri(baseUri));
                _tableStorage = new sqlTableClient(baseUri);//, info);
                //_tableStorage.RetryPolicy = _tableRetry;
                if (_tableStorage.CreateTableIfNotExist(_tableName))
                {
                    var ctx      = _tableStorage.GetDataServiceContext();
                    var dummyRow = new RoleRow("dummy", "fake", "none");
                    ctx.AddObject(_tableName, dummyRow);
                    ctx.SaveChangesWithRetries();
                    ctx.DeleteObject(dummyRow);
                    ctx.SaveChangesWithRetries();
                }
            }
            catch (SecurityException)
            {
                throw;
            }
            // catch InvalidOperationException as well as StorageException
            catch (Exception e)
            {
                //string exceptionDescription = Configuration.GetInitExceptionDescription(info, new Uri(baseUri), "table storage configuration");
                string exceptionDescription = Configuration.GetInitExceptionDescription(new Uri(baseUri), "table storage configuration");
                string tableName            = (_tableName == null) ? "no role table name specified" : _tableName;
                Log.Write(EventKind.Error, "Could not create or find role table: " + tableName + "!" + Environment.NewLine +
                          exceptionDescription + Environment.NewLine +
                          e.Message + Environment.NewLine + e.StackTrace);
                throw new ProviderException("Could not create or find role table. The most probable reason for this is that " +
                                            "the storage endpoints are not configured correctly. Please look at the configuration settings " +
                                            "in your .cscfg and Web.config files. More information about this error " +
                                            "can be found in the logs when running inside the hosting environment or in the output " +
                                            "window of Visual Studio.", e);
            }
        }