/// <summary>
        /// Save a new module or changes to an existing module.
        /// </summary>
        /// <param name="status">The status to designate for the module.</param>
        private Modules.ModuleInfo saveModule(ModuleStatus status)
        {
            // tells whether old data exists that needs to be
            // removed before adding any new data
            bool removePrevious = false;

            // tells whether user is just updating an existing
            // module or if they want to create a new module
            // (possibly a new version of an existing module)
            bool isUpdate = false;

            Modules.ModuleInfo mi = createModuleInfo();

            ModuleID           = mi.Id;
            ErrorMessage.Text += "Getting base ID for module: " + ModuleID;

            if (ModuleID > 0)
            {
                mi.BaseId = Modules.getModuleInfo(ModuleID).BaseId;
            }
            else
            {
                mi.BaseId = 0;
            }

            mi.Status      = status;
            mi.Submitter   = User.Identity.Name;
            mi.SubmitterID = UserAccounts.getUserInfo(User.Identity.Name).SubmitterID;

            switch (ModuleEditType)
            {
            case EditType.New:

                isUpdate = false;

                break;

            case EditType.InProgress:

                isUpdate       = true;
                removePrevious = true;

                break;

            case EditType.Approved:
                Modules.ModuleInfo oldModule = Modules.getModuleInfo(ModuleID);
                mi.BaseId = oldModule.BaseId;
                // If this module was previously Approved, and an admin changed it,
                // just update the module without creating a new version.
                if (User.Identity.IsAuthenticated && User.IsInRole(UserRole.Admin.ToString()))
                {
                    string modSubmitter = oldModule.Submitter;
                    // If this module is the admin's own, behave as if not an admin.
                    // Admins deserve multiple versions too.
                    if (User.Identity.Name.Equals(modSubmitter))
                    {
                        isUpdate   = false;
                        mi.Version = oldModule.Version + 1;
                    }
                    else
                    {
                        mi.Submitter   = modSubmitter;
                        mi.SubmitterID = oldModule.SubmitterID;

                        isUpdate   = true;
                        mi.Version = oldModule.Version;
                    }
                }
                // If this module was previously Approved, and a non-admin changed
                // it, create a new version of the module, and check it out accordingly.
                else
                {
                    isUpdate = false;
                    MaterialsControl1.retrieveMaterials(oldModule.Id);
                    mi.Version = oldModule.Version + 1;
                }
                removePrevious = true;

                break;
            }

            try
            {
                ModuleID = ModulesControl.checkInModule(mi, isUpdate);

                ErrorMessage.Text += " Assigned ModuleID = " + ModuleID + ".  ";

                mi.Id = ModuleID;

                foreach (IEditControl ec in editControls)
                {
                    ec.insertAll(ModuleID, removePrevious);
                }

                /** HANDLE THE VARIANTS **/

                // is true if this module is new OR a variant is chosen (including <None>)
                if (VariantOf != -1)
                {
                    int groupID = ModuleGroups.getGroupID(mi.BaseId);

                    // if this module was reset as a variant of the same module
                    // as before, or if it was set as a variant of a module in
                    // the same group as it already is in, do nothing
                    if (groupID != -1 && groupID == ModuleGroups.getGroupID(VariantOf))
                    {
                    }
                    // if this module was already in a group by itself, and the
                    // user tries to put it in a new group by itself, ignore
                    // the request and do nothing
                    else if (groupID != -1 && VariantOf == 0 && ModuleGroups.getRelatedModules(mi.BaseId).Count == 0)
                    {
                    }
                    else
                    {
                        // if <None> was chosen, add this module to its own module group
                        if (VariantOf == 0)
                        {
                            ModuleGroups.addToNew(mi.BaseId);
                        }
                        // else add this module to the group that was chosen
                        // SQL code resolves duplicates
                        else
                        {
                            ModuleGroups.addToExisting(mi.BaseId, VariantOf);
                        }
                    }
                }
                else
                {
                    // If the module was not a variant, add this module to its own module group
                    ModuleGroups.addToNew(mi.BaseId);
                }
            }
            catch (Exception e)
            {
                string message = "An error occurred while saving your module.";

                // If a new module was being created and there was an error, remove
                // the module (and by cascading, any added pieces).
                if (ModuleEditType == EditType.New && ModuleID != 0)
                {
                    ModulesControl.removeModule(ModuleID);
                    message += "  Module was not saved.  Review the module and try to resubmit it.";
                }
                else
                {
                    message       += "  All of your changes were not saved.  Review the module and try to resubmit it.";
                    ModuleEditType = EditType.InProgress;
                }

                // send an email to admins reporting the error
                Email msg = Emails.getEmail(EmailType.CriticalError);
                Emails.formatEmail(msg, mi.Submitter, mi.Id);
                Emails.formatEmailBody(msg, e.StackTrace + "::" + e.Message);
                MailMessage mail = Emails.constructErrorMessage(msg, Globals.AdminsEmail);
                SmtpMail.SmtpServer = AspNetForums.Components.Globals.SmtpServer;
                SmtpMail.Send(mail);

                message += " An e-mail reporting the error has been sent to the SWEnet Administrators.";
                throw new Exception(message, e);
            }

            return(mi);
        }