/// <summary>
        /// Takes, as input, a list of user names and a list of role names and removes the
        /// specified users from the specified roles.
        /// </summary>
        /// <remarks>
        /// This is the main implementation for the <c>RemoveUsersFromRoles</c> method of the provider. Please
        /// see the corresponding method in the Facade, which calls this method, for full documentaion.
        /// </remarks>
        /// <param name="usernames">The array of usernames.</param>
        /// <param name="roleNames">The array of roles.</param>
        internal void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            // Validate the input parameters
            ValidationUtil.CheckArrayParameterIsOk(ref roleNames, true, true, true, 256, "roleNames");
            ValidationUtil.CheckArrayParameterIsOk(ref usernames, true, true, true, 256, "usernames");

            // Instantiate lists to hold the calculated user and role Ids.
            List <string> userIdsList = new List <string>();
            List <string> roleIdsList = new List <string>();

            // Ensure that all of the roleNames are valid
            foreach (string username in usernames)
            {
                string userId = this.GetUserIdByName(username);

                if (userId == null)
                {
                    throw new ProviderException(string.Format(Messages.UserWasNotFound, username));
                }

                userIdsList.Add(userId);
            }

            // Ensure that all of the roleNames are valid
            foreach (string rolename in roleNames)
            {
                string roleId = this.GetRoleIdByName(rolename);

                if (roleId == null)
                {
                    throw new ProviderException(string.Format(Messages.RoleNotFound, rolename));
                }

                roleIdsList.Add(roleId);
            }

            // Ensure that the users are actually the the roles to begin with!
            foreach (string username in usernames)
            {
                foreach (string rolename in roleNames)
                {
                    if (!this.IsUserInRole(username, rolename))
                    {
                        throw new ProviderException(string.Format(Messages.UserAlreadyNotInRole, username, rolename));
                    }
                }
            }

            // Build up the SQL string
            string sql = @"
                            DELETE FROM aspnet_UsersInRoles 
                            WHERE 
                                UserId = ? 
                            AND RoleId = ? 
                           ";

            // Create a new command and enrol in the current transaction.
            IngresCommand cmd = new IngresCommand(sql, this.conn);

            cmd.Transaction    = this.tran;
            cmd.CommandTimeout = this.config.CommandTimeout;

            // Add the required parameters
            IngresParameter userParm = cmd.Parameters.Add("UserId", DbType.String);
            IngresParameter roleParm = cmd.Parameters.Add("RoleId", DbType.String);

            // For each user
            foreach (string userId in userIdsList)
            {
                // For each role
                foreach (string roleId in roleIdsList)
                {
                    userParm.Value = userId;
                    roleParm.Value = roleId;

                    // Remove the user from the role
                    cmd.ExecuteNonQuery();
                }
            }
        }
        /// <summary>
        /// Takes, as input, a list of user names and a list of role names and adds the specified
        /// users to the specified roles.
        /// </summary>
        /// <remarks>
        /// This is the main implementation for the <c>AddUsersToRoles</c> method of the provider. Please
        /// see the corresponding method in the Facade, which calls this method, for full documentaion.
        /// </remarks>
        /// <param name="usernames">A list of user names.</param>
        /// <param name="roleNames">A list of roles.</param>
        internal void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            // Note: Most of this validation is also done by the .NET framework - however I will
            // explicitly do it here also.
            ValidationUtil.CheckArrayParameterIsOk(ref roleNames, true, true, true, 256, "roleNames");
            ValidationUtil.CheckArrayParameterIsOk(ref usernames, true, true, true, 256, "usernames");

            // Ensure that all of the roleNames are valid.
            foreach (string rolename in roleNames)
            {
                if (!this.RoleExists(rolename))
                {
                    throw new ProviderException(string.Format(Messages.RoleNotFound, rolename));
                }
            }

            // Ensure that all of the usernames are valid.
            foreach (string username in usernames)
            {
                if (!this.UserExists(username))
                {
                    throw new ProviderException(string.Format(Messages.UserWasNotFound, username));
                }
            }

            // Ensure that all of the users actually are in the roles.
            foreach (string username in usernames)
            {
                foreach (string rolename in roleNames)
                {
                    if (this.IsUserInRole(username, rolename))
                    {
                        throw new ProviderException(string.Format(Messages.UserAlreadyInRole, username, rolename));
                    }
                }
            }

            // Instantiate a string to hold the required SQL
            string sql = @"
                            INSERT INTO aspnet_UsersInRoles
                               (UserId,
                                RoleId)
                            VALUES
                               (?, 
                                ?)
                           ";

            // Create a new command and enrol in the current transaction
            IngresCommand cmd = new IngresCommand(sql, this.conn);

            cmd.Transaction    = this.tran;
            cmd.CommandTimeout = this.config.CommandTimeout;

            // Add the required parameters
            IngresParameter userParam = cmd.Parameters.Add("UserId", DbType.String);
            IngresParameter roleParam = cmd.Parameters.Add("RoleId", DbType.String);

            // Note: this if a bit "row at a time" style rather than "chunk at a time"
            // processing - however it makes for easier to read and understand code and
            // allows for a static parameterized SQL string. If performance is poor then
            // this could be changed.

            // for each user
            foreach (string username in usernames)
            {
                // obtain the user id
                string userId = this.GetUserIdByName(username);

                // for each rolename
                foreach (string rolename in roleNames)
                {
                    // obtain role id
                    string roleId = this.GetRoleIdByName(rolename);

                    userParam.Value = userId;
                    roleParam.Value = roleId;

                    // try to add user to role
                    // The number of rows affected
                    int rows = cmd.ExecuteNonQuery();

                    // One row should be affected
                    if (rows != 1)
                    {
                        throw new ProviderException(string.Format(Messages.UnknownError));
                    }
                }
            }
        }