/// <summary> Constructor for a new instance of the Builder_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        public Builder_AdminViewer(User_Object User, SobekCM_Navigation_Object Current_Mode)
            : base(User)
        {
            currentMode = Current_Mode;

            // Ensure the user is the system admin
            if ((User == null) || ((!User.Is_System_Admin) && (!User.Is_Portal_Admin )))
            {
                Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                Current_Mode.Redirect();
                return;
            }

               // If this is a postback, handle any events first
            if ((Current_Mode.isPostBack) && ( User.Is_System_Admin ))
            {
                // Pull the hidden value
                string save_value = HttpContext.Current.Request.Form["admin_builder_tosave"].ToUpper().Trim();
                if (save_value.Length > 0)
                {
                    // Set this value
                    SobekCM_Database.Set_Setting("Builder Operation Flag", save_value);
                    Current_Mode.Redirect();
                }
            }
        }
        /// <summary> Constructor for a new instance of the ManageMenu_ItemViewer class </summary>
        /// <param name="Current_Object"> Digital resource to display </param>
        /// <param name="Current_User"> Current user for this session </param>
        /// <param name="Current_Mode"> Navigation object which encapsulates the user's current request </param>
        public ManageMenu_ItemViewer(SobekCM_Item Current_Object, User_Object Current_User, SobekCM_Navigation_Object Current_Mode)
        {
            // Save the current user and current mode information (this is usually populated AFTER the constructor completes,
            // but in this case (QC viewer) we need the information for early processing
            CurrentMode = Current_Mode;
            CurrentUser = Current_User;
            CurrentItem = Current_Object;

            // Determine if this user can edit this item
            if (CurrentUser == null)
            {
                Current_Mode.ViewerCode = String.Empty;
                Current_Mode.Redirect();
                return;
            }
            else
            {
                bool userCanEditItem = CurrentUser.Can_Edit_This_Item(CurrentItem);
                if (!userCanEditItem)
                {
                    Current_Mode.ViewerCode = String.Empty;
                    Current_Mode.Redirect();
                    return;
                }
            }
        }
        /// <summary> init viewer instance </summary>
        public Google_Coordinate_Entry_ItemViewer(User_Object Current_User, SobekCM_Item Current_Item, SobekCM_Navigation_Object Current_Mode)
        {
            try
            {

            CurrentUser = Current_User;
            CurrentItem = Current_Item;
            CurrentMode = Current_Mode;

            //string resource_directory = SobekCM_Library_Settings.Image_Server_Network + CurrentItem.Web.AssocFilePath;
            //string current_mets = resource_directory + CurrentItem.METS_Header.ObjectID + ".mets.xml";

            // If there is no user, send to the login
            if (CurrentUser == null)
            {
                CurrentMode.Mode = Display_Mode_Enum.My_Sobek;
                CurrentMode.My_Sobek_Type = My_Sobek_Type_Enum.Logon;
                CurrentMode.Return_URL = Current_Item.BibID + "/" + Current_Item.VID + "/mapedit";
                CurrentMode.Redirect();
                return;
            }

            //holds actions from page
            string action = HttpContext.Current.Request.Form["action"] ?? String.Empty;
            string payload = HttpContext.Current.Request.Form["payload"] ?? String.Empty;

            // See if there were hidden requests
            if (!String.IsNullOrEmpty(action))
            {
               if ( action == "save")
                   SaveContent(payload);
            }

            ////create a backup of the mets
            //string backup_directory = SobekCM_Library_Settings.Image_Server_Network + Current_Item.Web.AssocFilePath + SobekCM_Library_Settings.Backup_Files_Folder_Name;
            //string backup_mets_name = backup_directory + "\\" + CurrentItem.METS_Header.ObjectID + "_" + DateTime.Now.Year + "_" + DateTime.Now.Month + "_" + DateTime.Now.Day + ".mets.bak";
            //File.Copy(current_mets, backup_mets_name);

            }
            catch (Exception ee)
            {
                //Custom_Tracer.Add_Trace("MapEdit Start Failure");
                throw new ApplicationException("MapEdit Start Failure");
            }
        }
        /// <summary> Constructor for a new instance of the Preferences_HtmlSubwriter class </summary>
        public Preferences_HtmlSubwriter( SobekCM_Navigation_Object Current_Mode )
        {
            currentMode = Current_Mode;

            // See if there was a hidden request
            string hidden_request = HttpContext.Current.Request.Form["hidden_request"] ?? String.Empty;

            if (hidden_request == "submit")
            {
                NameValueCollection form = HttpContext.Current.Request.Form;

                string language_option = form["languageDropDown"];
                switch (language_option)
                {
                    case "en":
                        currentMode.Language = Web_Language_Enum.English;
                        break;

                    case "fr":
                        currentMode.Language = Web_Language_Enum.French;
                        break;

                    case "es":
                        currentMode.Language = Web_Language_Enum.Spanish;
                        break;

                }

                string defaultViewDropDown = form["defaultViewDropDown"];
                HttpContext.Current.Session["User_Default_View"] = defaultViewDropDown;

                int user_sort = Convert.ToInt32(form["defaultSortDropDown"]);
                HttpContext.Current.Session["User_Default_Sort"] = user_sort;

                currentMode.Mode = Display_Mode_Enum.Aggregation;
                currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
                currentMode.Redirect();

            }
        }
        /// <summary> Constructor for a new instance of the Users_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="currentMode"> Mode / navigation information for the current request</param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from a user edit or from reseting a user's password is handled here in the constructor </remarks>
        public Users_AdminViewer(User_Object User, SobekCM_Navigation_Object currentMode, Aggregation_Code_Manager Code_Manager, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Users_AdminViewer.Constructor", String.Empty);

            this.currentMode = currentMode;

            // Ensure the user is the system admin
            if ((User == null) || (!User.Is_System_Admin))
            {
                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Set the action message to clear initially
            actionMessage = String.Empty;
            codeManager = Code_Manager;

            // Get the user to edit, if there was a user id in the submode
            editUser = null;
            if (currentMode.My_Sobek_SubMode.Length > 0)
            {
                try
                {
                    int edit_userid = Convert.ToInt32(currentMode.My_Sobek_SubMode.Replace("a", "").Replace("b", "").Replace("c", "").Replace("v", ""));

                    // Check this admin's session for this user object
                    Object sessionEditUser = HttpContext.Current.Session["Edit_User_" + edit_userid];
                    if (sessionEditUser != null)
                        editUser = (User_Object)sessionEditUser;
                    else
                    {
                        editUser = SobekCM_Database.Get_User(edit_userid, Tracer);
                        editUser.Should_Be_Able_To_Edit_All_Items = false;
                        if (editUser.Editable_Regular_Expressions.Any(thisRegularExpression => thisRegularExpression == "[A-Z]{2}[A-Z|0-9]{4}[0-9]{4}"))
                        {
                            editUser.Should_Be_Able_To_Edit_All_Items = true;
                        }
                    }
                }
                catch (Exception)
                {
                    actionMessage = "Error while handing your request";
                }
            }

            // Determine the mode
            mode = Users_Admin_Mode_Enum.List_Users_And_Groups;
            if (editUser != null)
            {
                mode = currentMode.My_Sobek_SubMode.IndexOf("v") > 0 ? Users_Admin_Mode_Enum.View_User : Users_Admin_Mode_Enum.Edit_User;
            }
            else
            {
                currentMode.My_Sobek_SubMode = String.Empty;
            }

            // Perform post back work
            if (currentMode.isPostBack)
            {
                if (mode == Users_Admin_Mode_Enum.List_Users_And_Groups)
                {
                    try
                    {
                        string reset_value = HttpContext.Current.Request.Form["admin_user_reset"];
                        if (reset_value.Length > 0)
                        {
                            int userid = Convert.ToInt32(reset_value);
                            User_Object reset_user = SobekCM_Database.Get_User(userid, Tracer);

                            // Create the random password
                            StringBuilder passwordBuilder = new StringBuilder();
                            Random randomGenerator = new Random(DateTime.Now.Millisecond);
                            while (passwordBuilder.Length < 12)
                            {
                                switch (randomGenerator.Next(0, 3))
                                {
                                    case 0:
                                        int randomNumber = randomGenerator.Next(65, 91);
                                        if ((randomNumber != 79) && (randomNumber != 75)) // Omit the 'O' and the 'K', confusing
                                            passwordBuilder.Append((char)randomNumber);
                                        break;

                                    case 1:
                                        int randomNumber2 = randomGenerator.Next(97, 123);
                                        if ((randomNumber2 != 111) && (randomNumber2 != 108) && (randomNumber2 != 107))  // Omit the 'o' and the 'l' and the 'k', confusing
                                            passwordBuilder.Append((char)randomNumber2);
                                        break;

                                    case 2:
                                        // Zero and one is omitted in this range, confusing
                                        int randomNumber3 = randomGenerator.Next(50, 58);
                                        passwordBuilder.Append((char)randomNumber3);
                                        break;
                                }
                            }
                            string password = passwordBuilder.ToString();

                            // Reset this password
                            if (!SobekCM_Database.Reset_User_Password(userid, password, true, Tracer))
                            {
                                actionMessage = "ERROR reseting password";
                            }
                            else
                            {

                                if (SobekCM_Database.Send_Database_Email(reset_user.Email, "my" + currentMode.SobekCM_Instance_Abbreviation.ToUpper() + " Password Reset", reset_user.Full_Name + ",\n\nYour my" + currentMode.SobekCM_Instance_Abbreviation.ToUpper() + " password has been reset to a temporary password.  The first time you logon, you will be required to change it.\n\n\tUsername: "******"\n\tPassword: "******"\n\nYour password is case-sensitive and must be entered exactly as it appears above when logging on.\n\nIf you have any questions or problems logging on, feel free to contact us at " + SobekCM_Library_Settings.System_Email + ", or reply to this email.\n\n" + currentMode.Base_URL + "my/home\n", false, false, -1, -1))
                                {
                                    if ((user.UserID == 1) || (user.UserID == 2))
                                        actionMessage = "Reset of password (" + password + ") for '" + reset_user.Full_Name + "' complete";
                                    else
                                        actionMessage = "Reset of password for '" + reset_user.Full_Name + "' complete";
                                }
                                else
                                {
                                    if ((user.UserID == 1) || (user.UserID == 2))
                                        actionMessage = "ERROR while sending new password (" + password + ") to '" + reset_user.Full_Name + "'!";
                                    else
                                        actionMessage = "ERROR while sending new password to '" + reset_user.Full_Name + "'!";
                                }
                            }
                        }
                    }
                    catch
                    {
                        actionMessage = "ERROR while checking postback";
                    }
                }

                if ((mode == Users_Admin_Mode_Enum.Edit_User) && (editUser != null))
                {
                    // Determine which page you are on
                    int page = 1;
                    if (currentMode.My_Sobek_SubMode.IndexOf("b") > 0)
                        page = 2;
                    else if (currentMode.My_Sobek_SubMode.IndexOf("c") > 0)
                        page = 3;

                    // Get a reference to this form
                    NameValueCollection form = HttpContext.Current.Request.Form;
                    string[] getKeys = form.AllKeys;

                    // Get the curret action
                    string action = form["admin_user_save"];

                    bool successful_save = true;
                    switch (page)
                    {
                        case 1:
                            string editTemplate = "Standard";
                            List<string> projects = new List<string>();
                            List<string> templates = new List<string>();

                            // First, set some flags to FALSE
                            editUser.Can_Submit = false;
                            editUser.Is_Internal_User = false;
                            editUser.Should_Be_Able_To_Edit_All_Items = false;
                            editUser.Is_System_Admin = false;
                            editUser.Is_Portal_Admin = false;
                            editUser.Include_Tracking_In_Standard_Forms = false;

                            // Step through each key
                            foreach (string thisKey in getKeys)
                            {
                                switch (thisKey)
                                {
                                    case "admin_user_submit":
                                        editUser.Can_Submit = true;
                                        break;

                                    case "admin_user_internal":
                                        editUser.Is_Internal_User = true;
                                        break;

                                    case "admin_user_editall":
                                        editUser.Should_Be_Able_To_Edit_All_Items = true;
                                        break;

                                    case "admin_user_deleteall":
                                        editUser.Can_Delete_All = true;
                                        break;

                                    case "admin_user_sysadmin":
                                        editUser.Is_System_Admin = true;
                                        break;

                                    case "admin_user_portaladmin":
                                        editUser.Is_Portal_Admin = true;
                                        break;

                                    case "admin_user_includetracking":
                                        editUser.Include_Tracking_In_Standard_Forms = true;
                                        break;

                                    case "admin_user_edittemplate":
                                        editTemplate = form["admin_user_edittemplate"];
                                        break;

                                    case "admin_user_organization":
                                        editUser.Organization = form["admin_user_organization"];
                                        break;

                                    case "admin_user_college":
                                        editUser.College = form["admin_user_college"];
                                        break;

                                    case "admin_user_department":
                                        editUser.Department = form["admin_user_department"];
                                        break;

                                    case "admin_user_unit":
                                        editUser.Unit = form["admin_user_unit"];
                                        break;

                                    case "admin_user_org_code":
                                        editUser.Organization_Code = form["admin_user_org_code"];
                                        break;

                                    default:
                                        if (thisKey.IndexOf("admin_user_template_") == 0)
                                        {
                                            templates.Add(thisKey.Replace("admin_user_template_", ""));
                                        }
                                        if (thisKey.IndexOf("admin_user_project_") == 0)
                                        {
                                            projects.Add(thisKey.Replace("admin_user_project_", ""));
                                        }
                                        break;
                                }
                            }

                            // Determine the name for the actual edit templates from the combo box selection
                            editUser.Edit_Template_Code = "edit";
                            editUser.Edit_Template_MARC_Code = "editmarc";
                            if (editTemplate == "internal")
                            {
                                editUser.Edit_Template_Code = "edit_internal";
                                editUser.Edit_Template_MARC_Code = "editmarc_internal";
                            }

                            // Determine if the projects and templates need to be updated
                            bool update_templates_projects = false;
                            if ((templates.Count != editUser.Templates.Count) || (projects.Count != editUser.Default_Metadata_Sets.Count))
                            {
                                update_templates_projects = true;
                            }
                            else
                            {
                                // Check all of the templates
                                if (templates.Any(template => !editUser.Templates.Contains(template)))
                                {
                                    update_templates_projects = true;
                                }

                                // Check all the projects
                                if (!update_templates_projects)
                                {
                                    if (projects.Any(project => !editUser.Default_Metadata_Sets.Contains(project)))
                                    {
                                        update_templates_projects = true;
                                    }
                                }
                            }

                            // Update the templates and projects, if requested
                            if (update_templates_projects)
                            {
                                // Get the last defaults
                                string default_project = String.Empty;
                                string default_template = String.Empty;
                                if (editUser.Default_Metadata_Sets.Count > 0)
                                    default_project = editUser.Default_Metadata_Sets[0];
                                if (editUser.Templates.Count > 0)
                                    default_template = editUser.Templates[0];

                                // Now, set the user's template and projects
                                editUser.Clear_Default_Metadata_Sets();
                                editUser.Clear_Templates();
                                foreach (string thisProject in projects)
                                {
                                    editUser.Add_Default_Metadata_Set(thisProject, false);
                                }
                                foreach (string thisTemplate in templates)
                                {
                                    editUser.Add_Template(thisTemplate, false);
                                }

                                // Try to add back the defaults, which won't do anything if
                                // the old defaults aren't in the new list
                                editUser.Set_Current_Default_Metadata(default_project);
                                editUser.Set_Default_Template(default_template);
                            }
                            break;

                        case 2:
                            // Check the user groups for update
                            bool update_user_groups = false;
                            DataTable userGroup = SobekCM_Database.Get_All_User_Groups(Tracer);
                            List<string> newGroups = new List<string>();
                            foreach (DataRow thisRow in userGroup.Rows)
                            {
                                if (form["group_" + thisRow["UserGroupID"]] != null)
                                {
                                    newGroups.Add(thisRow["GroupName"].ToString());
                                }
                            }

                            // Should we add the new user groups?  Did it change?
                            if (newGroups.Count != editUser.User_Groups.Count)
                            {
                                update_user_groups = true;
                            }
                            else
                            {
                                foreach (string thisGroup in newGroups)
                                {
                                    if (!editUser.User_Groups.Contains(thisGroup))
                                    {
                                        update_user_groups = true;
                                        break;
                                    }
                                }
                            }
                            if (update_user_groups)
                            {
                                editUser.Clear_UserGroup_Membership();
                                foreach (string thisUserGroup in newGroups)
                                    editUser.Add_User_Group(thisUserGroup);
                            }
                            break;

                        case 3:
                            Dictionary<string, User_Editable_Aggregation> aggregations = new Dictionary<string, User_Editable_Aggregation>();

                            // Step through each key
                            foreach (string thisKey in getKeys)
                            {
                                if (thisKey.IndexOf("admin_project_onhome_") == 0)
                                {
                                    string select_project = thisKey.Replace("admin_project_onhome_", "");
                                    if (aggregations.ContainsKey(select_project))
                                    {
                                        aggregations[select_project].OnHomePage = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(select_project, new User_Editable_Aggregation(select_project, String.Empty, false, false, false, true, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_select_") == 0)
                                {
                                    string select_project = thisKey.Replace("admin_project_select_", "");
                                    if (aggregations.ContainsKey(select_project))
                                    {
                                        aggregations[select_project].CanSelect = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(select_project, new User_Editable_Aggregation(select_project, String.Empty, true, false, false, false, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_editall_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_edit_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanEditItems = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(edit_project, new User_Editable_Aggregation(edit_project, String.Empty, false, true, false, false, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_edit_metadata_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_edit_metadata_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanEditMetadata = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanEditMetadata = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_edit_behavior_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_edit_behavior_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanEditBehaviors = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanEditBehaviors = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_perform_qc_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_perform_qc_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanPerformQc = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanPerformQc = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_upload_files_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_upload_files_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanUploadFiles = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanUploadFiles = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_change_visibility_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_change_visibility_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanChangeVisibility = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanChangeVisibility = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_can_delete_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_can_delete_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanDelete = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanDelete = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_curator_") == 0)
                                {
                                    string admin_project = thisKey.Replace("admin_project_curator_", "");
                                    if (aggregations.ContainsKey(admin_project))
                                    {
                                        aggregations[admin_project].IsCurator = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(admin_project, new User_Editable_Aggregation(admin_project, String.Empty, false, false, true, false, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_admin_") == 0)
                                {
                                    string admin_project = thisKey.Replace("admin_project_admin_", "");
                                    if (aggregations.ContainsKey(admin_project))
                                    {
                                        aggregations[admin_project].IsAdmin = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(admin_project, new User_Editable_Aggregation(admin_project, String.Empty, false, false, false, false, true));
                                    }
                                }
                            }

                            // Determine if the aggregations need to be edited
                            bool update_aggregations = false;
                            if (aggregations.Count != editUser.Aggregations.Count)
                            {
                                update_aggregations = true;
                            }
                            else
                            {
                                // Build a dictionary of the user aggregations as well
                                Dictionary<string, User_Editable_Aggregation> existingAggr = editUser.Aggregations.ToDictionary(thisAggr => thisAggr.Code);

                                // Check all the aggregations
                                foreach (User_Editable_Aggregation adminAggr in aggregations.Values)
                                {
                                    if (existingAggr.ContainsKey(adminAggr.Code))
                                    {
                                        if ((adminAggr.CanSelect != existingAggr[adminAggr.Code].CanSelect) || (adminAggr.CanEditMetadata != existingAggr[adminAggr.Code].CanEditMetadata) ||
                                            (adminAggr.CanEditBehaviors != existingAggr[adminAggr.Code].CanEditBehaviors) || (adminAggr.CanPerformQc != existingAggr[adminAggr.Code].CanPerformQc) ||
                                            (adminAggr.CanUploadFiles != existingAggr[adminAggr.Code].CanUploadFiles) || (adminAggr.CanChangeVisibility != existingAggr[adminAggr.Code].CanChangeVisibility) ||
                                            (adminAggr.CanDelete != existingAggr[adminAggr.Code].CanDelete) || (adminAggr.IsCurator != existingAggr[adminAggr.Code].IsCurator) || (adminAggr.OnHomePage != existingAggr[adminAggr.Code].OnHomePage))
                                        {
                                            update_aggregations = true;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        update_aggregations = true;
                                        break;
                                    }
                                }
                            }

                            // Update the aggregations, if requested
                            if (update_aggregations)
                            {
                                editUser.Clear_Aggregations();
                                if (aggregations.Count > 0)
                                {
                                    foreach (User_Editable_Aggregation dictionaryAggregation in aggregations.Values)
                                    {
                                        editUser.Add_Aggregation(dictionaryAggregation.Code, dictionaryAggregation.Name, dictionaryAggregation.CanSelect, dictionaryAggregation.CanEditMetadata, dictionaryAggregation.CanEditBehaviors, dictionaryAggregation.CanPerformQc, dictionaryAggregation.CanUploadFiles, dictionaryAggregation.CanChangeVisibility, dictionaryAggregation.CanDelete, dictionaryAggregation.IsCurator, dictionaryAggregation.OnHomePage, dictionaryAggregation.IsAdmin, false);
                                    }
                                }
                            }
                            break;
                    }

                    // Should this be saved to the database?
                    if (action == "save")
                    {
                        // Save this user
                        SobekCM_Database.Save_User(editUser, String.Empty, user.Authentication_Type, Tracer);

                        // Update the basic user information
                        SobekCM_Database.Update_SobekCM_User(editUser.UserID, editUser.Can_Submit, editUser.Is_Internal_User, editUser.Should_Be_Able_To_Edit_All_Items, editUser.Can_Delete_All, editUser.Is_System_Admin, editUser.Is_Portal_Admin, editUser.Include_Tracking_In_Standard_Forms, editUser.Edit_Template_Code, editUser.Edit_Template_MARC_Code, true, true, true, Tracer);

                        // Update projects, if necessary
                        if (editUser.Default_Metadata_Sets.Count > 0)
                        {
                            if (!SobekCM_Database.Update_SobekCM_User_DefaultMetadata(editUser.UserID, editUser.Default_Metadata_Sets, Tracer))
                            {
                                successful_save = false;
                            }
                        }

                        // Update templates, if necessary
                        if (editUser.Templates.Count > 0)
                        {
                            if (!SobekCM_Database.Update_SobekCM_User_Templates(editUser.UserID, editUser.Templates, Tracer))
                            {
                                successful_save = false;
                            }
                        }

                        // Save the aggregations linked to this user
                        if (!SobekCM_Database.Update_SobekCM_User_Aggregations(editUser.UserID, editUser.Aggregations, Tracer))
                        {
                            successful_save = false;
                        }

                        // Save the user group links
                        DataTable userGroup = SobekCM_Database.Get_All_User_Groups(Tracer);
                        Dictionary<string, int> groupnames_to_id = new Dictionary<string, int>();
                        foreach (DataRow thisRow in userGroup.Rows)
                        {
                            groupnames_to_id[thisRow["GroupName"].ToString()] = Convert.ToInt32(thisRow["UserGroupID"]);
                        }
                        foreach (string userGroupName in editUser.User_Groups)
                        {
                            SobekCM_Database.Link_User_To_User_Group(editUser.UserID, groupnames_to_id[userGroupName]);
                        }

                        // Forward back to the list of users, if this was successful
                        if (successful_save)
                        {
                            // Clear the user from the sessions
                            HttpContext.Current.Session["Edit_User_" + editUser.UserID] = null;

                            // Redirect the user
                            currentMode.My_Sobek_SubMode = String.Empty;
                            currentMode.Redirect();
                        }
                    }
                    else
                    {
                        // Save to the admins session
                        HttpContext.Current.Session["Edit_User_" + editUser.UserID] = editUser;
                        currentMode.My_Sobek_SubMode = action;
                        currentMode.Redirect();
                    }
                }
            }
        }
        /// <summary> Constructor for a new instance of the Portals_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="URL_Portals"> List of all web portals into this system </param>
        /// <param name="Web_Skin_Collection"> Contains the collection of all the default skins and the data to create any additional skins on request</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Portals_AdminViewer(User_Object User, SobekCM_Navigation_Object Current_Mode, Portal_List URL_Portals, SobekCM_Skin_Collection Web_Skin_Collection, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Portals_AdminViewer.Constructor", String.Empty);

            portals = URL_Portals;
            skinCollection = Web_Skin_Collection;

            // Save the mode
            currentMode = Current_Mode;

            // Set action message to nothing to start
            actionMessage = String.Empty;

            // If the user cannot edit this, go back
            if (( user == null ) || ((!user.Is_System_Admin) && ( !user.Is_Portal_Admin )))
            {
                Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Handle any post backs
            if ((Current_Mode.isPostBack) && ( user.Is_System_Admin ))
            {
                try
                {
                    // Pull the standard values from the form
                    NameValueCollection form = HttpContext.Current.Request.Form;
                    string save_value = form["admin_portal_tosave"];
                    string action_value = form["admin_portal_action"];

                    // Switch, depending on the request
                    if (action_value != null)
                    {
                        switch (action_value.Trim().ToLower())
                        {
                            case "edit":
                                // Get the values from the form for this new portal
                                string edit_name = form["form_portal_name"].Trim();
                                string edit_abbr = form["form_portal_abbr"].Trim();
                                string edit_skin = form["form_portal_skin"].Trim();
                                string edit_aggr = form["form_portal_aggregation"].Trim();
                                string edit_url = form["form_portal_url"].Trim();
                                string edit_purl = form["form_portal_purl"].Trim();
                                int portalid = Convert.ToInt32(save_value);

                                // Look for this to see if this was the pre-existing default
                                bool isDefault = portals.Default_Portal.ID == portalid;

                                // Don't edit if the URL segment is empty and this is NOT default
                                if ((!isDefault) && (edit_url.Trim().Length == 0))
                                {
                                    actionMessage = "ERROR: Non default portals MUST have a url segment associated.";
                                }
                                else
                                {
                                    // Now, save this portal information
                                    int edit_id = SobekCM_Database.Edit_URL_Portal(portalid, edit_url, true, isDefault, edit_abbr, edit_name, edit_aggr, edit_skin, edit_purl, Tracer);
                                    if (edit_id > 0)
                                        actionMessage = "Edited existing URL portal '" + edit_name + "'";
                                    else
                                        actionMessage = "Error editing URL portal.";
                                }
                                break;

                            case "delete":
                                actionMessage = SobekCM_Database.Delete_URL_Portal(Convert.ToInt32(save_value), Tracer) ? "URL portal deleted" : "Error deleting the URL portal";
                                break;

                            case "new":
                                // Get the values from the form for this new portal
                                string new_name = form["admin_portal_name"];
                                string new_abbr = form["admin_portal_abbr"];
                                string new_skin = form["admin_portal_skin"];
                                string new_aggr = form["admin_portal_aggregation"];
                                string new_url = form["admin_portal_url"];
                                string new_purl = form["admin_portal_purl"];

                                // Save this to the database
                                int new_id = SobekCM_Database.Edit_URL_Portal(-1, new_url, true, false, new_abbr, new_name, new_aggr, new_skin, new_purl, Tracer);
                                if (new_id > 0)
                                    actionMessage = "Saved new URL portal '" + new_name + "'";
                                else
                                    actionMessage = "Error saving URL portal.";
                                break;
                        }
                    }
                }
                catch (Exception)
                {
                    actionMessage = "Exception caught while handling request";
                }

                // Reload all the URL portals
                SobekCM_Database.Populate_URL_Portals(portals, Tracer);
            }
        }
        /// <summary> Constructor for a new instance of the Edit_Item_Metadata_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="All_Items_Lookup"> Allows individual items to be retrieved by various methods as <see cref="Single_Item"/> objects.</param>
        /// <param name="Current_Item"> Individual digital resource to be edited by the user </param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Icon_Table"> Dictionary of all the wordmark/icons which can be tagged to the items </param>
        /// <param name="HTML_Skin_Collection"> HTML Web skin collection which controls the overall appearance of this digital library </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Edit_Item_Metadata_MySobekViewer(User_Object User,
            SobekCM_Navigation_Object Current_Mode,
            Item_Lookup_Object All_Items_Lookup,
            SobekCM_Item Current_Item, Aggregation_Code_Manager Code_Manager,
            Dictionary<string, Wordmark_Icon> Icon_Table,
            SobekCM_Skin_Object HTML_Skin,
            Language_Support_Info Translator,
            SobekCM_Skin_Collection HTML_Skin_Collection,
            Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Edit_Item_Metadata_MySobekViewer.Constructor", String.Empty);

            currentMode = Current_Mode;
            item = Current_Item;
            itemList = All_Items_Lookup;
            codeManager = Code_Manager;
            iconList = Icon_Table;
            webSkin = HTML_Skin;
            popUpFormsHtml = String.Empty;
            delayed_popup = String.Empty;
            base.Translator = Translator;
            skins = HTML_Skin_Collection;

            // If the user cannot edit this item, go back
            if (!user.Can_Edit_This_Item( item ))
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                HttpContext.Current.Response.Redirect(currentMode.Redirect_URL());
            }

            // Is this a project
            isProject = item.Bib_Info.SobekCM_Type == TypeOfResource_SobekCM_Enum.Project;

            string template_code = user.Edit_Template_Code;
            if ((isProject) || (item.Contains_Complex_Content) || (item.Using_Complex_Template))
            {
                template_code = user.Edit_Template_MARC_Code;
            }
            template = Cached_Data_Manager.Retrieve_Template(template_code, Tracer);
            if (template != null)
            {
                Tracer.Add_Trace("Edit_Item_Metadata_MySobekViewer.Constructor", "Found template in cache");
            }
            else
            {
                Tracer.Add_Trace("Edit_Item_Metadata_MySobekViewer.Constructor", "Reading template file");

                // Read this template
                Template_XML_Reader reader = new Template_XML_Reader();
                template = new Template();
                reader.Read_XML( SobekCM_Library_Settings.Base_MySobek_Directory + "templates\\edit\\" + template_code + ".xml", template, true);

                // Add the current codes to this template
                template.Add_Codes(Code_Manager);

                // Save this into the cache
                Cached_Data_Manager.Store_Template(template_code, template, Tracer);
            }

            // Get the current page number, or default to 1
            page = 1;
            if (currentMode.My_Sobek_SubMode.Length > 0)
            {
                if ((currentMode.My_Sobek_SubMode == "preview") || (currentMode.My_Sobek_SubMode == "marc") || (currentMode.My_Sobek_SubMode == "mets"))
                {
                    page = 0;
                }
                else
                {
                    page = 1;
                    bool isNumber = currentMode.My_Sobek_SubMode.All(Char.IsNumber);
                    if (isNumber)
                    {
                        if (isProject)
                            Double.TryParse(currentMode.My_Sobek_SubMode[0].ToString(), out page);
                        else
                            Double.TryParse(currentMode.My_Sobek_SubMode, out page);
                    }
                    else if ( isProject )
                    {
                        if ( Char.IsNumber(currentMode.My_Sobek_SubMode[0]))
                            Double.TryParse(currentMode.My_Sobek_SubMode[0].ToString(), out page);
                    }
                }
            }

            // Handle post backs
            if (Current_Mode.isPostBack)
            {
                // See if there was a hidden request
                string hidden_request = HttpContext.Current.Request.Form["new_element_requested"] ?? String.Empty;

                // If this was a cancel request do that
                if (hidden_request == "cancel")
                {
                    if (isProject)
                    {
                        Cached_Data_Manager.Remove_Project(user.UserID, item.BibID, null);

                        currentMode.Mode = Display_Mode_Enum.Administrative;
                        currentMode.Admin_Type = Admin_Type_Enum.Default_Metadata;
                        currentMode.My_Sobek_SubMode = String.Empty;
                        currentMode.Redirect();
                    }
                    else
                    {
                        Cached_Data_Manager.Remove_Digital_Resource_Object(user.UserID, item.BibID, item.VID, null);

                        currentMode.Mode = Display_Mode_Enum.Item_Display;
                        currentMode.Redirect();
                    }
                    return;
                }

                // Save these changes to bib
                template.Save_To_Bib(item, user, ((int) page));

                // See if the user asked for a new element of a complex form type
                delayed_popup = String.Empty;
                switch (hidden_request.Trim())
                {
                    case "name":
                        delayed_popup = "name";
                        item.Bib_Info.Add_Named_Entity(String.Empty).Name_Type = Name_Info_Type_Enum.personal;
                        break;

                    case "title":
                        delayed_popup = "title";
                        item.Bib_Info.Add_Other_Title(String.Empty, Title_Type_Enum.alternative);
                        break;

                    case "subject":
                        delayed_popup = "subject";
                        item.Bib_Info.Add_Subject();
                        break;

                    case "spatial":
                        delayed_popup = "spatial";
                        item.Bib_Info.Add_Hierarchical_Geographic_Subject();
                        break;

                    case "relateditem":
                        delayed_popup = "relateditem";
                        item.Bib_Info.Add_Related_Item(new Related_Item_Info());
                        break;

                    case "save":
                        Complete_Item_Save();
                        break;

                    case "complicate":
                        item.Using_Complex_Template = true;
                        HttpContext.Current.Response.Redirect( "?" + HttpContext.Current.Request.QueryString, false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        currentMode.Request_Completed = true;
                        return;

                    case "simplify":
                        item.Using_Complex_Template = false;
                        HttpContext.Current.Response.Redirect( "?" + HttpContext.Current.Request.QueryString, false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        currentMode.Request_Completed = true;
                        return;
                }

                // Was this for a new page?
                if (hidden_request.IndexOf("newpage") == 0)
                {
                    string page_requested = hidden_request.Replace("newpage", "");
                    if (page_requested != currentMode.My_Sobek_SubMode)
                    {
                        // forward to requested page
                        currentMode.My_Sobek_SubMode = page_requested;
                        if (currentMode.My_Sobek_SubMode == "0")
                            currentMode.My_Sobek_SubMode = "preview";
                        if (isProject)
                            currentMode.My_Sobek_SubMode = page_requested + item.BibID;

                        HttpContext.Current.Response.Redirect(currentMode.Redirect_URL() + "#template", false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        currentMode.Request_Completed = true;
                    }
                }
            }
        }
        /// <summary> Constructor for a new instance of the IP_Restrictions_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="CurrentMode"> Mode / navigation information for the current request</param>
        /// <param name="IP_Restrictions"> List of all IP restrictions ranges used in this digital library to restrict access to certain digital resources </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling an edit or new item aggregation alias is handled here in the constructor </remarks>
        public IP_Restrictions_AdminViewer( User_Object User, SobekCM_Navigation_Object CurrentMode, IP_Restriction_Ranges IP_Restrictions, Custom_Tracer Tracer )
            : base(User)
        {
            Tracer.Add_Trace("IP_Restrictions_AdminViewer.Constructor", String.Empty);

            ipRestrictionInfo = IP_Restrictions;
            currentMode = CurrentMode;

            // Ensure the user is the system admin
            if ((User == null) || ((!User.Is_System_Admin) && ( !User.Is_Portal_Admin )))
            {
                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Determine if there is an specific IP address range for editing
            index = -1;
            if (currentMode.My_Sobek_SubMode.Length > 0)
            {
                if ( !Int32.TryParse(currentMode.My_Sobek_SubMode, out index ))
                    index = -1;
            }

            // If there was an index included, try to pull the information about it
            thisRange = null;
            details = null;
            if ((index >= 1) && (index <= ipRestrictionInfo.Count))
            {
                thisRange = ipRestrictionInfo[index - 1];
                if (thisRange != null)
                {
                    details = SobekCM_Database.Get_IP_Restriction_Range_Details(thisRange.RangeID, Tracer);
                }
            }

            if ((currentMode.isPostBack) && ( user.Is_System_Admin ))
            {
                // Get a reference to this form
                NameValueCollection form = HttpContext.Current.Request.Form;

                string action = form["action"].Trim();

                if (action == "new")
                {
                    // Pull the main values
                    string title = form["new_admin_title"].Trim();
                    string notes = form["new_admin_notes"].Trim();
                    string message = form["new_admin_message"].Trim();

                    if ((title.Length == 0) || (message.Length == 0))
                    {
                        actionMessage = "Both title and message are required fields";
                    }
                    else
                    {
                        if ( SobekCM_Database.Edit_IP_Range(-1, title, notes, message, Tracer))
                            actionMessage = "Saved new IP range '" + title + "'";
                        else
                            actionMessage = "Error saving new IP range '" + title + "'";
                    }
                }
                else if (( details != null ) && ( thisRange != null ))
                {
                    try
                    {
                        // Pull the main values
                        string title = form["admin_title"].Trim();
                        string notes = form["admin_notes"].Trim();
                        string message = form["admin_message"].Trim();

                        if (title.Length == 0)
                        {
                            title = thisRange.Title;
                        }

                        // Edit the main values in the database
                        SobekCM_Database.Edit_IP_Range(thisRange.RangeID, title, notes, message, Tracer);
                        thisRange.Title = title;
                        thisRange.Notes = notes;
                        thisRange.Item_Restricted_Statement = message;

                        // Now check each individual IP address range
                        string[] getKeys = form.AllKeys;
                        int single_ip_index = 0;
                        foreach (string thisKey in getKeys)
                        {
                            // Is this for a new ip address?
                            if (thisKey.IndexOf("admin_ipstart_") == 0)
                            {
                                // Get the basic information for this single ip address
                                string ip_index = thisKey.Replace("admin_ipstart_", "");
                                string thisIpStart = form["admin_ipstart_" + ip_index].Trim();
                                string thisIpEnd = form["admin_ipend_" + ip_index].Trim();
                                string thisIpNote = form["admin_iplabel_" + ip_index].Trim();

                                // Does this match an existing IP range?
                                if ((ip_index.IndexOf("new") < 0) && (single_ip_index < details.Tables[1].Rows.Count))
                                {
                                    // Get the pre-existing IP row
                                    DataRow ipRow = details.Tables[1].Rows[single_ip_index];
                                    int singleIpId = Convert.ToInt32(ipRow[0]);
                                    if (thisIpStart.Length == 0)
                                    {
                                        SobekCM_Database.Delete_Single_IP(singleIpId, Tracer);
                                    }
                                    else
                                    {
                                        // Is this the same?
                                        if ((thisIpStart != ipRow[1].ToString().Trim()) || (thisIpEnd != ipRow[2].ToString().Trim()) || (thisIpNote != ipRow[3].ToString().Trim()))
                                        {
                                            int edit_point_count = thisIpStart.Count(ThisChar => ThisChar == '.');

                                            if (edit_point_count == 3)
                                            {
                                                SobekCM_Database.Edit_Single_IP(singleIpId, thisRange.RangeID, thisIpStart, thisIpEnd, thisIpNote, Tracer);
                                            }
                                        }
                                    }

                                    // Be ready to look at the next pre-existing IP range
                                    single_ip_index++;
                                }
                                else
                                {
                                    // Just add this as a new single ip address
                                    if (thisIpStart.Length > 0)
                                    {
                                        int add_point_count = thisIpStart.Count(ThisChar => ThisChar == '.');

                                        if (add_point_count == 3)
                                        {
                                            SobekCM_Database.Edit_Single_IP(-1, thisRange.RangeID, thisIpStart, thisIpEnd, thisIpNote, Tracer);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        actionMessage = "Error saving IP range";
                    }
                }

                // Repopulate the restriction table
                DataTable ipRestrictionTbl = SobekCM_Database.Get_IP_Restriction_Ranges(Tracer);
                if (ipRestrictionTbl != null)
                {
                    IP_Restrictions.Populate_IP_Ranges(ipRestrictionTbl);
                }

                // Forward back to the main form
                if (String.IsNullOrEmpty(actionMessage))
                {
                    currentMode.My_Sobek_SubMode = String.Empty;
                    currentMode.Redirect();
                }
            }
        }
        /// <summary> Constructor for a new instance of the New_Group_And_Item_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Current_Item"> Digital resource selected for file management </param>
        /// <param name="Item_List"> Allows individual items to be retrieved by various methods as <see cref="Single_Item"/> objects.</param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Icon_Table"> Dictionary of all the wordmark/icons which can be tagged to the items </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Page_Image_Upload_MySobekViewer(User_Object User,
                                             SobekCM_Navigation_Object Current_Mode,
                                             SobekCM_Item Current_Item,
                                             Item_Lookup_Object Item_List,
                                             Aggregation_Code_Manager Code_Manager,
                                             Dictionary<string, Wordmark_Icon> Icon_Table,
                                             SobekCM_Skin_Object HTML_Skin,
                                             Language_Support_Info Translator,
                                             Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Page_Image_Upload_MySobekViewer.Constructor", String.Empty);

            // Save the parameters
            codeManager = Code_Manager;
            itemList = Item_List;
            iconList = Icon_Table;
            currentMode = Current_Mode;
            webSkin = HTML_Skin;
            this.validationErrors = validationErrors;
            base.Translator = Translator;
            item = Current_Item;

            // If the user cannot edit this item, go back
            if (!user.Can_Edit_This_Item(item))
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Determine the in process directory for this
            digitalResourceDirectory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + User.UserName.Replace(".", "").Replace("@", "") + "\\uploadimages\\" + Current_Item.METS_Header.ObjectID;
            if (User.ShibbID.Trim().Length > 0)
                digitalResourceDirectory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + User.ShibbID + "\\uploadimages\\" + Current_Item.METS_Header.ObjectID;

            // Make the folder for the user in process directory
            if (!Directory.Exists(digitalResourceDirectory))
                Directory.CreateDirectory(digitalResourceDirectory);
            else
            {
                // Any post-processing to do?
                string[] files = Directory.GetFiles(digitalResourceDirectory);
                foreach (string thisFile in files)
                {
                    FileInfo thisFileInfo = new FileInfo(thisFile);
                    if ((thisFileInfo.Extension.ToUpper() == ".TIF") || (thisFileInfo.Extension.ToUpper() == ".TIFF"))
                    {
                        // Is there a JPEG and/or thumbnail?
                        string jpeg = digitalResourceDirectory + "\\" + thisFileInfo.Name.Replace(thisFileInfo.Extension, "") + ".jpg";
                        string jpeg_thumbnail = digitalResourceDirectory + "\\" + thisFileInfo.Name.Replace(thisFileInfo.Extension, "") + "thm.jpg";

                        // Is one missing?
                        if ((!File.Exists(jpeg)) || (!File.Exists(jpeg_thumbnail)))
                        {
                            try
                            {
                                var tiffImg = System.Drawing.Image.FromFile(thisFile);
                                var mainImg = ScaleImage(tiffImg, SobekCM_Library_Settings.JPEG_Width, SobekCM_Library_Settings.JPEG_Height);
                                mainImg.Save(jpeg, ImageFormat.Jpeg);
                                var thumbnailImg = ScaleImage(tiffImg, 150, 400);
                                thumbnailImg.Save(jpeg_thumbnail, ImageFormat.Jpeg);

                            }
                            catch (Exception)
                            {
                                bool error = true;
                            }
                        }
                    }
                }
            }

            // If this is post-back, handle it
            if (currentMode.isPostBack)
            {
                string[] getKeys = HttpContext.Current.Request.Form.AllKeys;
                string file_name_from_keys = String.Empty;
                string label_from_keys = String.Empty;
                foreach (string thisKey in getKeys)
                {
                    if (thisKey.IndexOf("upload_file") == 0)
                    {
                        file_name_from_keys = HttpContext.Current.Request.Form[thisKey];
                    }
                    if (thisKey.IndexOf("upload_label") == 0)
                    {
                        label_from_keys = HttpContext.Current.Request.Form[thisKey];
                    }
                    if ((file_name_from_keys.Length > 0) && (label_from_keys.Length > 0))
                    {
                        HttpContext.Current.Session["file_" + item.Web.ItemID + "_" + file_name_from_keys.Trim()] = label_from_keys.Trim();
                        file_name_from_keys = String.Empty;
                        label_from_keys = String.Empty;
                    }

                    if (thisKey == "url_input")
                    {
                        item.Bib_Info.Location.Other_URL = HttpContext.Current.Request.Form[thisKey];
                    }
                }

                string action = HttpContext.Current.Request.Form["action"];
                if (action == "delete")
                {
                    string filename = HttpContext.Current.Request.Form["phase"];
                    try
                    {
                        if (File.Exists(digitalResourceDirectory + "\\" + filename))
                            File.Delete(digitalResourceDirectory + "\\" + filename);

                        // Forward
                        currentMode.Redirect();
                        return;
                    }
                    catch
                    {
                        // Error was caught during attempted delete
                    }
                }

                if ( action == "next_phase")
                {
                    int phase = Convert.ToInt32(HttpContext.Current.Request.Form["phase"]);
                    switch( phase )
                    {
                        case 2:
                            // Clear all the file keys in the temporary folder
                            string[] allFiles = Directory.GetFiles(digitalResourceDirectory);
                            foreach (string thisFile in allFiles)
                            {
                                try
                                {
                                    File.Delete(thisFile);
                                }
                                catch
                                {
                                    // Do nothing - not a fatal problem
                                }
                            }

                            try
                            {
                                Directory.Delete(digitalResourceDirectory);
                            }
                            catch
                            {
                                // Do nothing - not a fatal problem
                            }

                            // Redirect to the item
                            currentMode.Mode = Display_Mode_Enum.Item_Display;
                            currentMode.Redirect();
                            break;

                        case 9:
                            if (!complete_item_submission(item, null))
                            {
                                // Also clear the item from the cache
                                Cached_Data_Manager.Remove_Digital_Resource_Object(item.BibID, item.VID, null);

                                // Redirect to the item
                                currentMode.Mode = Display_Mode_Enum.Item_Display;
                                currentMode.ViewerCode = "qc";
                                currentMode.Redirect();
                            }
                            break;
                    }
                }
            }
        }
        /// <summary> Constructor for a new instance of the User_Group_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="currentMode"> Mode / navigation information for the current request</param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from a user group edit is handled here in the constructor </remarks>
        public User_Group_AdminViewer(User_Object User, SobekCM_Navigation_Object currentMode, Aggregation_Code_Manager Code_Manager, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("User_Group_AdminViewer.Constructor", String.Empty);

            // Set the action message to clear initially
            actionMessage = String.Empty;
            codeManager = Code_Manager;

            // Get the user to edit, if there was a user id in the submode
            int edit_usergroupid = -100;
            editGroup = null;
            if (currentMode.My_Sobek_SubMode.Length > 0)
            {
                if (currentMode.My_Sobek_SubMode == "new")
                {
                    edit_usergroupid = -1;
                }
                else
                {
                    if (Int32.TryParse(currentMode.My_Sobek_SubMode.Replace("a", "").Replace("b", "").Replace("c", "").Replace("v", ""), out edit_usergroupid))
                        editGroup = SobekCM_Database.Get_User_Group(edit_usergroupid, Tracer);
                }
            }

            // Determine the mode
            mode = Users_Group_Admin_Mode_Enum.Error;
            if ((editGroup != null) || (edit_usergroupid == -1))
            {
                if ((currentMode.My_Sobek_SubMode.IndexOf("v") > 0) && (edit_usergroupid > 0))
                    mode = Users_Group_Admin_Mode_Enum.View_User_Group;
                else
                    mode = Users_Group_Admin_Mode_Enum.Edit_User_Group;
            }
            else
            {
                currentMode.My_Sobek_SubMode = String.Empty;
                currentMode.Admin_Type = Admin_Type_Enum.Users;
                currentMode.Redirect();
                return;
            }

            // Set an empty user group object for a new item
            if (edit_usergroupid < 0)
            {
                editGroup = new User_Group(String.Empty, String.Empty, -1);
            }

            // Perform post back work
            if (currentMode.isPostBack)
            {
                if ((mode == Users_Group_Admin_Mode_Enum.Edit_User_Group) && (editGroup != null))
                {
                    // Get a reference to this form
                    NameValueCollection form = HttpContext.Current.Request.Form;
                    string[] getKeys = form.AllKeys;

                    bool successful_save = true;
                    bool can_editall = editGroup.Editable_Regular_Expressions.Any(thisRegularExpression => thisRegularExpression == "[A-Z]{2}[A-Z|0-9]{4}[0-9]{4}");

                    bool can_submit = false;
                    bool is_internal = false;
                    bool is_admin = false;
                    bool is_portal = false;
                    string name = editGroup.Name;
                    string description = editGroup.Description;
                    bool is_sobek_default = false;
                    bool is_shibboleth_default = false;
                    bool is_ldap_default = false;

                    List<string> projects = new List<string>();
                    List<string> templates = new List<string>();

                    Dictionary<string, User_Editable_Aggregation> aggregations = new Dictionary<string, User_Editable_Aggregation>();

                    // Step through each key
                    foreach (string thisKey in getKeys)
                    {
                        switch (thisKey)
                        {
                            case "groupName":
                                name = form[thisKey].Trim();
                                break;

                            case "groupDescription":
                                description = form[thisKey].Trim();
                                break;

                            case "admin_user_submit":
                                can_submit = true;
                                break;

                            case "admin_user_internal":
                                is_internal = true;
                                break;

                            case "admin_user_editall":
                                can_editall = true;
                                break;

                            case "admin_user_admin":
                                is_admin = true;
                                break;

                            case "admin_user_portaladmin":
                                is_portal = true;
                                break;

                            default:
                                if (thisKey.IndexOf("admin_user_template_") == 0)
                                {
                                    templates.Add(thisKey.Replace("admin_user_template_", ""));
                                }
                                if (thisKey.IndexOf("admin_user_project_") == 0)
                                {
                                    projects.Add(thisKey.Replace("admin_user_project_", ""));
                                }
                                if (thisKey.IndexOf("admin_project_onhome_") == 0)
                                {
                                    string select_project = thisKey.Replace("admin_project_onhome_", "");
                                    if (aggregations.ContainsKey(select_project))
                                    {
                                        aggregations[select_project].OnHomePage = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(select_project, new User_Editable_Aggregation(select_project, String.Empty, false, false, false, true, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_select_") == 0)
                                {
                                    string select_project = thisKey.Replace("admin_project_select_", "");
                                    if (aggregations.ContainsKey(select_project))
                                    {
                                        aggregations[select_project].CanSelect = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(select_project, new User_Editable_Aggregation(select_project, String.Empty, true, false, false, false, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_editall_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_editall_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanEditItems = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(edit_project, new User_Editable_Aggregation(edit_project, String.Empty, false, true, false, false, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_edit_metadata_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_edit_metadata_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanEditMetadata = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanEditMetadata = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_edit_behavior_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_edit_behavior_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanEditBehaviors = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanEditBehaviors = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_perform_qc_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_perform_qc_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanPerformQc = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanPerformQc = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_upload_files_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_upload_files_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanUploadFiles = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanUploadFiles = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_change_visibility_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_change_visibility_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanChangeVisibility = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanChangeVisibility = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_can_delete_") == 0)
                                {
                                    string edit_project = thisKey.Replace("admin_project_can_delete_", "");
                                    if (aggregations.ContainsKey(edit_project))
                                    {
                                        aggregations[edit_project].CanDelete = true;
                                    }
                                    else
                                    {
                                        User_Editable_Aggregation thisAggrLink = new User_Editable_Aggregation(edit_project, String.Empty, false, false, false, false, false);
                                        thisAggrLink.CanDelete = true;
                                        aggregations.Add(edit_project, thisAggrLink);
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_curator_") == 0)
                                {
                                    string admin_project = thisKey.Replace("admin_project_curator_", "");
                                    if (aggregations.ContainsKey(admin_project))
                                    {
                                        aggregations[admin_project].IsCurator = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(admin_project, new User_Editable_Aggregation(admin_project, String.Empty, false, false, true, false, false));
                                    }
                                }
                                if (thisKey.IndexOf("admin_project_admin_") == 0)
                                {
                                    string admin_project = thisKey.Replace("admin_project_admin_", "");
                                    if (aggregations.ContainsKey(admin_project))
                                    {
                                        aggregations[admin_project].IsAdmin = true;
                                    }
                                    else
                                    {
                                        aggregations.Add(admin_project, new User_Editable_Aggregation(admin_project, String.Empty, false, false, false, false, true));
                                    }
                                }
                                break;
                        }
                    }

                    // Determine if the projects and templates need to be updated
                    bool update_templates_projects = false;
                    if ((templates.Count != editGroup.Templates.Count) || (projects.Count != editGroup.Default_Metadata_Sets.Count))
                    {
                        update_templates_projects = true;
                    }
                    else
                    {
                        // Check all of the templates
                        if (templates.Any(template => !editGroup.Templates.Contains(template)))
                        {
                            update_templates_projects = true;
                        }

                        // Check all the projects
                        if (!update_templates_projects)
                        {
                            if (projects.Any(project => !editGroup.Default_Metadata_Sets.Contains(project)))
                            {
                                update_templates_projects = true;
                            }
                        }
                    }

                    // Determine if the aggregations need to be edited
                    bool update_aggregations = false;
                    if (aggregations.Count != editGroup.Aggregations.Count)
                    {
                        update_aggregations = true;
                    }
                    else
                    {
                        // Build a dictionary of the user aggregations as well
                        Dictionary<string, User_Editable_Aggregation> existingAggr = editGroup.Aggregations.ToDictionary(thisAggr => thisAggr.Code);

                        // Check all the aggregations
                        foreach (User_Editable_Aggregation adminAggr in aggregations.Values)
                        {
                            if (existingAggr.ContainsKey(adminAggr.Code))
                            {
                                if ((adminAggr.CanSelect != existingAggr[adminAggr.Code].CanSelect) || (adminAggr.CanEditMetadata != existingAggr[adminAggr.Code].CanEditMetadata) ||
                                                (adminAggr.CanEditBehaviors != existingAggr[adminAggr.Code].CanEditBehaviors) || (adminAggr.CanPerformQc != existingAggr[adminAggr.Code].CanPerformQc) ||
                                                (adminAggr.CanUploadFiles != existingAggr[adminAggr.Code].CanUploadFiles) || (adminAggr.CanChangeVisibility != existingAggr[adminAggr.Code].CanChangeVisibility) ||
                                                (adminAggr.CanDelete != existingAggr[adminAggr.Code].CanDelete) || (adminAggr.IsCurator != existingAggr[adminAggr.Code].IsCurator) || (adminAggr.OnHomePage != existingAggr[adminAggr.Code].OnHomePage))
                                {
                                    update_aggregations = true;
                                    break;
                                }
                            }
                            else
                            {
                                update_aggregations = true;
                                break;
                            }
                        }
                    }

                    // Must have a name to continue
                    if (name.Length > 0)
                    {
                        // Update the basic user information
                        int newid = SobekCM_Database.Save_User_Group(editGroup.UserGroupID, name, description, can_submit, is_internal, can_editall, is_admin, is_portal, false, update_templates_projects, update_aggregations, false, is_sobek_default, is_shibboleth_default, is_ldap_default, Tracer);
                        if (editGroup.UserGroupID < 0)
                        {
                            editGroup.UserGroupID = newid;
                        }

                        if (editGroup.UserGroupID > 0)
                        {
                            // Update the templates and projects, if requested
                            if (update_templates_projects)
                            {
                                // Update projects, if necessary
                                if (projects.Count > 0)
                                {
                                    if (!SobekCM_Database.Update_SobekCM_User_Group_DefaultMetadata(editGroup.UserGroupID, projects, Tracer))
                                    {
                                        successful_save = false;
                                    }
                                }

                                // Update templates, if necessary
                                if (templates.Count > 0)
                                {
                                    if (!SobekCM_Database.Update_SobekCM_User_Group_Templates(editGroup.UserGroupID, templates, Tracer))
                                    {
                                        successful_save = false;
                                    }
                                }
                            }

                            // Update the aggregations, if requested
                            if (update_aggregations)
                            {
                                if (aggregations.Count > 0)
                                {
                                    List<User_Editable_Aggregation> aggregationList = aggregations.Values.ToList();
                                    if (!SobekCM_Database.Update_SobekCM_User_Group_Aggregations(editGroup.UserGroupID, aggregationList, Tracer))
                                    {
                                        successful_save = false;
                                    }
                                }
                            }
                        }
                        else
                        {
                            successful_save = false;
                        }
                    }
                    else
                    {
                        actionMessage = "User group's name must have a length greater than zero";
                        successful_save = false;
                    }

                    // Forward back to the list of users, if this was successful
                    if (successful_save)
                    {
                        currentMode.My_Sobek_SubMode = String.Empty;
                        currentMode.Redirect();
                    }
                }
            }
        }
        /// <summary> Constructor for a new instance of the Group_Add_Volume_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="All_Items_Lookup"> Allows individual items to be retrieved by various methods as <see cref="Single_Item"/> objects.</param>
        /// <param name="Current_Item"> Individual digital resource to be edited by the user </param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Icon_Table"> Dictionary of all the wordmark/icons which can be tagged to the items </param>
        /// <param name="Items_In_Title"> List of items within this title </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="HTML_Skin_Collection"> HTML Web skin collection which controls the overall appearance of this digital library </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Group_Add_Volume_MySobekViewer(User_Object User,
            SobekCM_Navigation_Object Current_Mode,
            Item_Lookup_Object All_Items_Lookup,
            SobekCM_Item Current_Item, Aggregation_Code_Manager Code_Manager,
            Dictionary<string, Wordmark_Icon> Icon_Table,
            SobekCM_Skin_Object HTML_Skin,
            SobekCM_Items_In_Title Items_In_Title,
            Language_Support_Info Translator,
			SobekCM_Skin_Collection HTML_Skin_Collection,
            Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Group_Add_Volume_MySobekViewer.Constructor", String.Empty);

            currentMode = Current_Mode;
            item = Current_Item;
            itemList = All_Items_Lookup;
            codeManager = Code_Manager;
            iconList = Icon_Table;
            webSkin = HTML_Skin;
            itemsInTitle = Items_In_Title;
            base.Translator = Translator;
            skins = HTML_Skin_Collection;

            // Set some defaults
            ipRestrict = -1;
            title = String.Empty;
            date = String.Empty;
            level1 = String.Empty;
            level2 = String.Empty;
            level3 = String.Empty;
            level1Order = -1;
            level2Order = -1;
            level3Order = -1;
            hierarchyCopiedFromDate = false;
            message = String.Empty;
            trackingBox = String.Empty;
            bornDigital = false;
            materialRecdDate = null;
            materialRecdNotes = String.Empty;
            dispositionAdvice = -1;
            dispositionAdviceNotes = String.Empty;

            // If the user cannot edit this item, go back
            if (!user.Can_Edit_This_Item(item))
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Determine the default template code
            string template_code = "addvolume";
            if (!user.Include_Tracking_In_Standard_Forms)
                template_code = "addvolume_notracking";

            // Load this template
            template = Cached_Data_Manager.Retrieve_Template(template_code, Tracer);
            if (template != null)
            {
                Tracer.Add_Trace("Group_Add_Volume_MySobekViewer.Constructor", "Found template in cache");
            }
            else
            {
                Tracer.Add_Trace("Group_Add_Volume_MySobekViewer.Constructor", "Reading template file");

                // Read this template
                Template_XML_Reader reader = new Template_XML_Reader();
                template = new Template();
                reader.Read_XML(SobekCM_Library_Settings.Base_MySobek_Directory + "templates\\defaults\\" + template_code + ".xml", template, true);

                // Add the current codes to this template
                template.Add_Codes(Code_Manager);

                // Save this into the cache
                Cached_Data_Manager.Store_Template(template_code, template, Tracer);
            }

            // See if there was a hidden request
            string hidden_request = HttpContext.Current.Request.Form["action"] ?? String.Empty;

            // If this was a cancel request do that
            if (hidden_request == "cancel")
            {
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.Redirect();
            }
            else if (hidden_request.IndexOf("save") == 0 )
            {
                // Get the VID that used as a source for this
                string vid = HttpContext.Current.Request.Form["base_volume"];

                if (string.IsNullOrEmpty(vid))
                {
                     message = "<span style=\"color: red\"><strong>No base volume selected!</strong></span>";
                }
                else
                {
                    try
                    {
                        // Get a new instance of this item
                        SobekCM_Item saveItem = SobekCM_Item_Factory.Get_Item(Current_Mode.BibID, vid, Icon_Table, null, Tracer);

                        // Clear some values for this item
                        saveItem.VID = String.Empty;
                        saveItem.Divisions.Clear();
                        saveItem.Behaviors.Serial_Info.Clear();
                        saveItem.Bib_Info.Series_Part_Info.Clear();
                        saveItem.Behaviors.Clear_Ticklers();
                        saveItem.Tracking.Internal_Comments = String.Empty;
                        saveItem.Bib_Info.Location.PURL = String.Empty;
                        saveItem.Behaviors.Main_Thumbnail = String.Empty;
                        saveItem.METS_Header.Create_Date = DateTime.Now;
                        saveItem.METS_Header.Modify_Date = saveItem.METS_Header.Create_Date;
                        saveItem.METS_Header.Creator_Software = "SobekCM Web - Online add a volume (derived from VID " + vid + ")";
                        saveItem.METS_Header.Clear_Creator_Individual_Notes();
                        saveItem.METS_Header.Creator_Individual = user.Full_Name;
                        saveItem.Bib_Info.Location.Other_URL = String.Empty;
                        saveItem.Bib_Info.Location.Other_URL_Display_Label = String.Empty;
                        saveItem.Bib_Info.Location.Other_URL_Note = String.Empty;

                        // Save the template changes to this item
                        template.Save_To_Bib(saveItem, user, 1);

                        // Save this item and copy over
                        complete_item_submission(saveItem, Tracer);

                        // Clear the volume list
                        Cached_Data_Manager.Remove_Items_In_Title(saveItem.BibID, Tracer);

                        // Forward differently depending on request
                        switch (hidden_request)
                        {
                            case "save_edit":
                                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Edit_Item_Metadata;
                                currentMode.VID = saveItem.VID;
                                currentMode.Redirect();
                                break;

                            case "save_again":
                                // No redirect, but save values
                                date = saveItem.Bib_Info.Origin_Info.Date_Issued;
                                ipRestrict = saveItem.Behaviors.IP_Restriction_Membership;
                                trackingBox = saveItem.Tracking.Tracking_Box;
                                bornDigital = saveItem.Tracking.Born_Digital;
                                dispositionAdvice = saveItem.Tracking.Disposition_Advice;
                                dispositionAdviceNotes = saveItem.Tracking.Disposition_Advice_Notes;
                                materialRecdDate = saveItem.Tracking.Material_Received_Date;
                                materialRecdNotes = saveItem.Tracking.Material_Received_Notes;
                                if (!hierarchyCopiedFromDate)
                                {
                                    if (saveItem.Behaviors.Serial_Info.Count > 0)
                                    {
                                        level1 = saveItem.Behaviors.Serial_Info[0].Display;
                                        level1Order = saveItem.Behaviors.Serial_Info[0].Order;
                                    }
                                    if (saveItem.Behaviors.Serial_Info.Count > 1)
                                    {
                                        level2 = saveItem.Behaviors.Serial_Info[1].Display;
                                        level2Order = saveItem.Behaviors.Serial_Info[1].Order;
                                    }
                                    if (saveItem.Behaviors.Serial_Info.Count > 2)
                                    {
                                        level3 = saveItem.Behaviors.Serial_Info[2].Display;
                                        level3Order = saveItem.Behaviors.Serial_Info[2].Order;
                                    }
                                }
                                message = message + "<span style=\"color: blue\"><strong>Saved new volume ( " + saveItem.BibID + " : " + saveItem.VID + ")</strong></span>";
                                break;

                            case "save_addfiles":
                                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.File_Management;
                                currentMode.VID = saveItem.VID;
                                currentMode.Redirect();
                                break;

                            default:
                                currentMode.Mode = Display_Mode_Enum.Item_Display;
                                currentMode.VID = saveItem.VID;
                                currentMode.Redirect();
                                break;
                        }

                    }
                    catch ( Exception ee )
                    {
                        message = message + "<br /><span style=\"color: red\"><strong>EXCEPTION CAUGHT!<br /><br />" + ee.Message + "<br /><br />" + ee.StackTrace.Replace("\n","<br />") + "</strong></span>";

                    }
                }
            }
        }
        /// <summary> Constructor for a new instance of the New_Group_And_Item_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Item_List"> Allows individual items to be retrieved by various methods as <see cref="Single_Item"/> objects.</param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Icon_Table"> Dictionary of all the wordmark/icons which can be tagged to the items </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="HTML_Skin_Collection"> HTML Web skin collection which controls the overall appearance of this digital library </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public New_Group_And_Item_MySobekViewer(User_Object User, 
                                                SobekCM_Navigation_Object Current_Mode, Item_Lookup_Object Item_List,
                                                Aggregation_Code_Manager Code_Manager,
                                                Dictionary<string, Wordmark_Icon> Icon_Table,
                                                SobekCM_Skin_Object HTML_Skin,
                                                Language_Support_Info Translator,
												SobekCM_Skin_Collection HTML_Skin_Collection,
                                                Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("New_Group_And_Item_MySobekViewer.Constructor", String.Empty);

            // Save the parameters
            currentMode = Current_Mode;
            codeManager = Code_Manager;
            iconList = Icon_Table;
            webSkin = HTML_Skin;
            base.Translator = Translator;
            skins = HTML_Skin_Collection;

            // If the user cannot submit items, go back
            if (!user.Can_Submit)
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }
            itemList = Item_List;

            // Determine the in process directory for this
            if (user.ShibbID.Trim().Length > 0)
                userInProcessDirectory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.ShibbID + "\\newgroup";
            else
                userInProcessDirectory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.UserName.Replace(".","").Replace("@","") + "\\newgroup";

            // Handle postback for changing the template or project
            templateCode = user.Current_Template;
            if (currentMode.isPostBack)
            {
                string action1 = HttpContext.Current.Request.Form["action"];
                if ((action1 != null) && ((action1 == "template") || (action1 == "project")))
                {
                    string newvalue = HttpContext.Current.Request.Form["phase"];
                    if ((action1 == "template") && ( newvalue != templateCode ))
                    {
                        user.Current_Template = newvalue;
                        templateCode = user.Current_Template;
                        if (File.Exists(userInProcessDirectory + "\\agreement.txt"))
                            File.Delete(userInProcessDirectory + "\\agreement.txt");
                    }
                    if ((action1 == "project") && (newvalue != user.Current_Default_Metadata))
                    {
                        user.Current_Default_Metadata = newvalue;
                    }
                    HttpContext.Current.Session["item"] = null;
                }
            }

            // Load the template
            templateCode = user.Current_Template;
            template = Cached_Data_Manager.Retrieve_Template(templateCode, Tracer);
            if ( template != null )
            {
                Tracer.Add_Trace("New_Group_And_Item_MySobekViewer.Constructor", "Found template in cache");
            }
            else
            {
                Tracer.Add_Trace("New_Group_And_Item_MySobekViewer.Constructor", "Reading template");

                // Read this template
                Template_XML_Reader reader = new Template_XML_Reader();
                template = new Template();
                reader.Read_XML( SobekCM_Library_Settings.Base_MySobek_Directory + "templates\\" + templateCode + ".xml", template, true);

                // Add the current codes to this template
                template.Add_Codes(Code_Manager);

                // Save this into the cache
                Cached_Data_Manager.Store_Template(templateCode, template, Tracer);
            }

            // Determine the number of total template pages
            totalTemplatePages = template.InputPages_Count;
            if (template.Permissions_Agreement.Length > 0)
                totalTemplatePages++;
            if (template.Upload_Types != Template.Template_Upload_Types.None)
                totalTemplatePages++;

            // Determine the title for this template, or use a default
            toolTitle = template.Title;
            if (toolTitle.Length == 0)
                toolTitle = "Self-Submittal Tool";

            // Determine the current phase
            currentProcessStep = 1;
            if ((currentMode.My_Sobek_SubMode.Length > 0) && (Char.IsNumber(currentMode.My_Sobek_SubMode[0])))
            {
                Int32.TryParse(currentMode.My_Sobek_SubMode.Substring(0), out currentProcessStep);
            }

            // If this is process step 1 and there is no permissions statement in the template,
            // just go to step 2
            if ((currentProcessStep == 1) && (template.Permissions_Agreement.Length == 0))
            {
                // Delete any pre-existing agreement from an earlier aborted submission process
                if (File.Exists(userInProcessDirectory + "\\agreement.txt"))
                    File.Delete(userInProcessDirectory + "\\agreement.txt");

                // Skip the permissions step
                currentProcessStep = 2;
            }

            // If there is a boundary infraction here, go back to step 2
            if (currentProcessStep < 0)
                currentProcessStep = 2;
            if ((currentProcessStep > template.InputPages.Count + 1 ) && ( currentProcessStep != 8 ) && ( currentProcessStep != 9 ))
                currentProcessStep = 2;

            // If this is to enter a file or URL, and the template does not include this, skip over this step
            if (( currentProcessStep == 8 ) && ( template.Upload_Types == Template.Template_Upload_Types.None ))
            {
                // For now, just forward to the next phase
                currentMode.My_Sobek_SubMode = "9";
                currentMode.Redirect();
                return;
            }

            // Look for the item in the session, then directory, then just create a new one
            if (HttpContext.Current.Session["Item"] == null)
            {
                // Clear any old files (older than 24 hours) that are in the directory
                if (!Directory.Exists(userInProcessDirectory))
                    Directory.CreateDirectory(userInProcessDirectory);
                else
                {
                    // Anything older than a day should be deleted
                    string[] files = Directory.GetFiles(userInProcessDirectory);
                    foreach (string thisFile in files)
                    {
                        DateTime modifiedDate = ((new FileInfo(thisFile)).LastWriteTime);
                        if (DateTime.Now.Subtract(modifiedDate).TotalHours > (24 * 7))
                        {
                            try
                            {
                                File.Delete(thisFile);
                            }
                            catch(Exception )
                            {
                                // Unable to delete existing file in the user's folder.
                                // This is an error, but how to report it?
                            }
                        }
                    }
                }

                // First, look for an existing METS file
                string[] existing_mets = Directory.GetFiles(userInProcessDirectory, "*.mets*");
                if (existing_mets.Length > 0)
                {
                    Tracer.Add_Trace("New_Group_And_Item_MySobekViewer.Constructor", "Reading existing METS file<br />(" + existing_mets[0] + ")");
                    item = SobekCM_Item.Read_METS(existing_mets[0]);

                    // Set the visibility information from the template
                    item.Behaviors.IP_Restriction_Membership = template.Default_Visibility;
                }

                // If there is still no item, just create a new one
                if (item == null)
                {
                    // Build a new empty METS file
                    new_item( Tracer );
                }

                // Save this to the session state now
                HttpContext.Current.Session["Item"] = item;
            }
            else
            {
                Tracer.Add_Trace("New_Group_And_Item_MySobekViewer.Constructor", "Item found in session cache");
                item = (SobekCM_Item)HttpContext.Current.Session["Item"];
            }

            #region Special code to handle any uploaded files

            // Any post-processing to do?
            if ((currentProcessStep == 8) && (Directory.Exists(userInProcessDirectory)))
            {
                string[] processFiles = Directory.GetFiles(userInProcessDirectory);
                foreach (string thisFile in processFiles)
                {
                    FileInfo thisFileInfo = new FileInfo(thisFile);
                    if ((thisFileInfo.Extension.ToUpper() == ".TIF") || (thisFileInfo.Extension.ToUpper() == ".TIFF"))
                    {
                        // Is there a JPEG and/or thumbnail?
                        string jpeg = userInProcessDirectory + "\\" + thisFileInfo.Name.Replace(thisFileInfo.Extension, "") + ".jpg";
                        string jpeg_thumbnail = userInProcessDirectory + "\\" + thisFileInfo.Name.Replace(thisFileInfo.Extension, "") + "thm.jpg";

                        // Is one missing?
                        if ((!File.Exists(jpeg)) || (!File.Exists(jpeg_thumbnail)))
                        {
                            using (System.Drawing.Image tiffImg = System.Drawing.Image.FromFile(thisFile))
                            {
                                try
                                {
                                    var mainImg = ScaleImage(tiffImg, SobekCM_Library_Settings.JPEG_Width, SobekCM_Library_Settings.JPEG_Height);
                                    mainImg.Save(jpeg, ImageFormat.Jpeg);
                                    mainImg.Dispose();
                                    var thumbnailImg = ScaleImage(tiffImg, 150, 400);
                                    thumbnailImg.Save(jpeg_thumbnail, ImageFormat.Jpeg);
                                    thumbnailImg.Dispose();
                                }
                                catch
                                {

                                }
                                finally
                                {
                                    if ( tiffImg != null )
                                        tiffImg.Dispose();
                                }
                            }

                        }
                    }
                }
            }

            #endregion

            #region Handle any other post back requests

            // If this is post-back, handle it
            if (currentMode.isPostBack)
            {
                // If this is a request from stage 8, save the new labels and url first
                if (currentProcessStep == 8)
                {
                    string[] getKeys = HttpContext.Current.Request.Form.AllKeys;
                    string file_name_from_keys = String.Empty;
                    string label_from_keys = String.Empty;
                    foreach (string thisKey in getKeys)
                    {
                        if (thisKey.IndexOf("upload_file") == 0)
                        {
                            file_name_from_keys = HttpContext.Current.Request.Form[thisKey];
                        }
                        if (thisKey.IndexOf("upload_label") == 0)
                        {
                            label_from_keys = HttpContext.Current.Request.Form[thisKey];
                        }
                        if ((file_name_from_keys.Length > 0) && (label_from_keys.Length > 0))
                        {
                            HttpContext.Current.Session["file_" + file_name_from_keys.Trim()] = label_from_keys.Trim();
                            file_name_from_keys = String.Empty;
                            label_from_keys = String.Empty;
                        }

                        if (thisKey == "url_input")
                        {
                            item.Bib_Info.Location.Other_URL = HttpContext.Current.Request.Form[thisKey];
                        }
                    }
                }

                string action = HttpContext.Current.Request.Form["action"];
                if (action == "cancel")
                {
                    // Clear all files in the user process folder
                    try
                    {
                        string[] all_files = Directory.GetFiles(userInProcessDirectory);
                        foreach (string thisFile in all_files)
                            Directory.Delete(thisFile);
                        Directory.Delete(userInProcessDirectory);
                    }
                    catch (Exception)
                    {
                        // Unable to delete existing file in the user's folder.
                        // This is an error, but how to report it?
                    }

                    // Clear all the information in memory
                    HttpContext.Current.Session["agreement_date"] = null;
                    HttpContext.Current.Session["item"] = null;

                    // Clear any temporarily assigned current project and template
                    user.Current_Default_Metadata = null;
                    user.Current_Template = null;

                    // Forward back to my Sobek home
                    currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                    currentMode.Redirect();
                }

                if ( action == "delete" )
                {
                    string filename = HttpContext.Current.Request.Form["phase"];
                    try
                    {
                        if (File.Exists(userInProcessDirectory + "\\" + filename))
                            File.Delete(userInProcessDirectory + "\\" + filename);

                        // Forward
                        currentMode.Redirect();
                        return;
                    }
                    catch (Exception)
                    {
                        // Unable to delete existing file in the user's folder.
                        // This is an error, but how to report it?
                    }
                }

                if (action == "clear")
                {
                    // If there is an old METS file, delete it
                    if (File.Exists(userInProcessDirectory + "\\TEMP000001_00001.mets"))
                        File.Delete(userInProcessDirectory + "\\TEMP000001_00001.mets");

                    // Create the new METS file and add to the session
                    new_item(null);
                    HttpContext.Current.Session["Item"] = item;

                    // Forward back to the same URL
                    currentMode.My_Sobek_SubMode = "2";
                    currentMode.Redirect();
                    return;
                }

                if (action == "next_phase")
                {

                    string next_phase = HttpContext.Current.Request.Form["phase"];

                    // If this goes from step 1 to step 2, write the permissions first
                    if ((currentProcessStep == 1) && (next_phase == "2") && ( template.Permissions_Agreement.Length > 0 ))
                    {
                        // Store this agreement in the session state
                        DateTime agreement_date = DateTime.Now;
                        HttpContext.Current.Session["agreement_date"] = agreement_date;

                        // Also, save this as a text file
                        string agreement_file = userInProcessDirectory + "\\agreement.txt";
                        StreamWriter writer = new StreamWriter(agreement_file, false);
                        writer.WriteLine("Permissions Agreement");
                        writer.WriteLine();
                        writer.WriteLine("User: "******" ( " + user.ShibbID + " )");
                        writer.WriteLine("Date: " + agreement_date.ToString());
                        writer.WriteLine();
                        writer.WriteLine(template.Permissions_Agreement);
                        writer.Flush();
                        writer.Close();

                        if (HttpContext.Current.Request.Form["setNewDefaultCheckBox"] != null )
                        {
                            string prefProject = HttpContext.Current.Request.Form["prefProject"];
                            string prefTemplate = HttpContext.Current.Request.Form["prefTemplate"];
                            user.Set_Default_Template(prefTemplate.Trim());
                            user.Set_Current_Default_Metadata(prefProject.Trim());
                            Database.SobekCM_Database.Save_User(user, String.Empty, user.Authentication_Type, Tracer);
                        }
                    }

                    // If this is going from a step that includes the metadata entry portion, save this to the item
                    if ((currentProcessStep > 1) && (currentProcessStep < 8))
                    {
                        // Save to the item
                        template.Save_To_Bib(item, user, currentProcessStep - 1);
                        item.Save_METS();
                        HttpContext.Current.Session["Item"] = item;

                        // Save the pertinent data to the METS file package
                        item.METS_Header.Create_Date = DateTime.Now;
                        if ((HttpContext.Current.Session["agreement_date"] != null) && (HttpContext.Current.Session["agreement_date"].ToString().Length > 0))
                        {
                            DateTime asDateTime;
                            if (DateTime.TryParse(HttpContext.Current.Session["agreement_date"].ToString(), out asDateTime))
                                item.METS_Header.Create_Date = asDateTime;
                        }
                        HttpContext.Current.Session["Item"] = item;

                        // Save this item, just in case it gets lost somehow
                        item.Source_Directory = userInProcessDirectory;
                        string acquisition_append = "Submitted by " + user.Full_Name + ".";
                        if (item.Bib_Info.Notes_Count > 0)
                        {
                            foreach (Note_Info thisNote in item.Bib_Info.Notes.Where(ThisNote => ThisNote.Note_Type == Note_Type_Enum.acquisition))
                            {
                                if (thisNote.Note.IndexOf(acquisition_append) < 0)
                                    thisNote.Note = thisNote.Note.Trim() + "  " + acquisition_append;
                                break;
                            }
                        }

                        // Also, check all the authors to add the current users attribution information
                        if (user.Organization.Length > 0)
                        {
                            if ((item.Bib_Info.Main_Entity_Name.Full_Name.IndexOf(user.Family_Name) >= 0) && ((item.Bib_Info.Main_Entity_Name.Full_Name.IndexOf(user.Given_Name) >= 0) || ((user.Nickname.Length > 2) && (item.Bib_Info.Main_Entity_Name.Full_Name.IndexOf(user.Nickname) > 0))))
                            {
                                item.Bib_Info.Main_Entity_Name.Affiliation = user.Organization;
                                if (user.College.Length > 0)
                                    item.Bib_Info.Main_Entity_Name.Affiliation = item.Bib_Info.Main_Entity_Name.Affiliation + " -- " + user.College;
                                if (user.Department.Length > 0)
                                    item.Bib_Info.Main_Entity_Name.Affiliation = item.Bib_Info.Main_Entity_Name.Affiliation + " -- " + user.Department;
                                if (user.Unit.Length > 0)
                                    item.Bib_Info.Main_Entity_Name.Affiliation = item.Bib_Info.Main_Entity_Name.Affiliation + " -- " + user.Unit;
                            }
                            if (item.Bib_Info.Names_Count > 0)
                            {
                                foreach (Name_Info thisName in item.Bib_Info.Names)
                                {
                                    if ((thisName.Full_Name.IndexOf(user.Family_Name) >= 0) && ((thisName.Full_Name.IndexOf(user.Given_Name) >= 0) || ((user.Nickname.Length > 2) && (thisName.Full_Name.IndexOf(user.Nickname) > 0))))
                                    {
                                        thisName.Affiliation = user.Organization;
                                        if (user.College.Length > 0)
                                            thisName.Affiliation = thisName.Affiliation + " -- " + user.College;
                                        if (user.Department.Length > 0)
                                            thisName.Affiliation = thisName.Affiliation + " -- " + user.Department;
                                        if (user.Unit.Length > 0)
                                            thisName.Affiliation = thisName.Affiliation + " -- " + user.Unit;

                                    }
                                }
                            }
                        }
                        item.Save_METS();
                        HttpContext.Current.Session["Item"] = item;
                    }

                    // For now, just forward to the next phase
                    currentMode.My_Sobek_SubMode = next_phase;
                    currentMode.Redirect();
                    return;
                }
            }

            #endregion

            #region Perform some validation to determine if the user should be at this step

            // If this is past the agreement phase, check that an agreement exists
            if (currentProcessStep > 1)
            {
                // Validate that an agreement.txt file exists, if the template has permissions
                if (( template.Permissions_Agreement.Length > 0 ) && (!File.Exists(userInProcessDirectory + "\\agreement.txt")))
                {
                    currentMode.My_Sobek_SubMode = "1";
                    currentMode.Redirect();
                    return;
                }

                // Get the validation errors
                validationErrors = new List<string>();
                SobekCM_Item_Validator.Validate_SobekCM_Item(item, validationErrors);
            }

            // If this is to put up items or complete the item, validate the METS
            if ( currentProcessStep >= 8 )
            {
                // Validate that a METS file exists
                if (Directory.GetFiles( userInProcessDirectory, "*.mets*").Length == 0 )
                {
                    currentMode.My_Sobek_SubMode = "2";
                    currentMode.Redirect();
                    return;
                }

                // Get the validation errors
                if ( validationErrors.Count == 0 )
                    item.Save_METS();
                else
                {
                    item.Web.Show_Validation_Errors = true;
                    currentMode.My_Sobek_SubMode = "2";
                    currentMode.Redirect();
                    return;
                }
            }

            // If this is for step 8, ensure that this even takes this information, or go to step 9
            if (( currentProcessStep == 8 ) && ( template.Upload_Types == Template.Template_Upload_Types.None ))
            {
                currentMode.My_Sobek_SubMode = "9";
                currentMode.Redirect();
                return;
            }

            // If this is going into the last process step, check that any mandatory info (file, url, .. )
            // from the last step is present
            if ( currentProcessStep == 9 )
            {
                // Only check if this is mandatory
                if (( template.Upload_Mandatory ) && ( template.Upload_Types != Template.Template_Upload_Types.None ))
                {
                    // Does this require either a FILE or URL?
                    bool required_file_present = false;
                    bool required_url_present = false;

                    // If this accepts files, check for acceptable files
                    if (( template.Upload_Types == Template.Template_Upload_Types.File ) || ( template.Upload_Types == Template.Template_Upload_Types.URL ))
                    {
                        // Get list of files in this package
                        string[] all_files = Directory.GetFiles(userInProcessDirectory);
                        List<string> acceptable_files = all_files.Where(ThisFile => (ThisFile.IndexOf("agreement.txt") < 0) && (ThisFile.IndexOf("TEMP000001_00001.mets") < 0)).ToList();

                        // Acceptable files found?
                        if ( acceptable_files.Count > 0 )
                            required_file_present = true;
                    }

                    // If this accepts URLs, check for a URL
                    if (( template.Upload_Types == Template.Template_Upload_Types.URL ) || ( template.Upload_Types == Template.Template_Upload_Types.File_or_URL ))
                    {
                        if ( item.Bib_Info.Location.Other_URL.Length > 0 )
                        {
                            required_url_present = true;
                        }
                    }

                    // If neither was present, go back to step 8
                    if (( !required_file_present ) && ( !required_url_present ))
                    {
                        currentMode.My_Sobek_SubMode = "8";
                        currentMode.Redirect();
                        return;
                    }
                }

                // Complete the item submission
                complete_item_submission( item,  Tracer );
            }

            #endregion
        }
        /// <summary> Constructor for a new instance of the QC_ItemViewer class </summary>
        /// <param name="Current_Object"> Digital resource to display </param>
        /// <param name="Current_User"> Current user for this session </param>
        /// <param name="Current_Mode"> Navigation object which encapsulates the user's current request </param>
        public QC_ItemViewer(SobekCM_Item Current_Object, User_Object Current_User, SobekCM_Navigation_Object Current_Mode)
        {
            // Save the current user and current mode information (this is usually populated AFTER the constructor completes,
            // but in this case (QC viewer) we need the information for early processing
            CurrentMode = Current_Mode;
            CurrentUser = Current_User;

            //Assign the current resource object to qc_item
            qc_item = Current_Object;
            //Save to the User's session
            HttpContext.Current.Session[Current_Object.BibID + "_" + Current_Object.VID + " QC Work"] = qc_item;

            // If there is no user, send to the login
            if (CurrentUser == null)
            {
                CurrentMode.Mode = Display_Mode_Enum.My_Sobek;
                CurrentMode.My_Sobek_Type = My_Sobek_Type_Enum.Logon;
                CurrentMode.Redirect();
                return;
            }

            // If the user cannot edit this item, go back
            if (!CurrentUser.Can_Edit_This_Item(Current_Object))
            {
                CurrentMode.ViewerCode = String.Empty;
                CurrentMode.Redirect();
                return;
            }

            //If there are no pages for this item, redirect to the image upload screen
            if (qc_item.Web.Static_PageCount == 0)
            {
                CurrentMode.Mode = Display_Mode_Enum.My_Sobek;
                CurrentMode.My_Sobek_Type = My_Sobek_Type_Enum.Page_Images_Management;
                CurrentMode.Redirect();
                return;
            }

            // Get the links for the METS
            string greenstoneLocation = Current_Object.Web.Source_URL + "/";
            complete_mets = greenstoneLocation + Current_Object.BibID + "_" + Current_Object.VID + ".mets.xml";

            // MAKE THIS USE THE FILES.ASPX WEB PAGE if this is restricted (or dark)
            if ((Current_Object.Behaviors.Dark_Flag) || (Current_Object.Behaviors.IP_Restriction_Membership > 0))
            {
                complete_mets = CurrentMode.Base_URL + "files/" + qc_item.BibID + "/" + qc_item.VID + "/" + qc_item.BibID + "_" + qc_item.VID + ".mets.xml";
            }

            // Get the special qc_item, which matches the passed in Current_Object, at least the first time.
            // If the QC work is already in process, we may find a temporary METS file to read.

            // Determine the in process directory for this
            userInProcessDirectory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + Current_User.UserName.Replace(".", "").Replace("@", "") + "\\qcwork\\" + qc_item.METS_Header.ObjectID;
            if (Current_User.ShibbID.Trim().Length > 0)
                userInProcessDirectory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + Current_User.ShibbID + "\\qcwork\\" + qc_item.METS_Header.ObjectID;

            // Make the folder for the user in process directory
            if (!Directory.Exists(userInProcessDirectory))
                Directory.CreateDirectory(userInProcessDirectory);

            // Create the name for the tempoary METS file?
            metsInProcessFile = userInProcessDirectory + "\\" + Current_Object.BibID + "_" + Current_Object.VID + ".mets.xml";

            // Is this work in the user's SESSION state?
            qc_item = HttpContext.Current.Session[Current_Object.BibID + "_" + Current_Object.VID + " QC Work"] as SobekCM_Item;
            if (qc_item == null)
            {

                // Is there a temporary METS for this item, which is not expired?
                if ((File.Exists(metsInProcessFile)) &&
                    (File.GetLastWriteTime(metsInProcessFile).Subtract(DateTime.Now).Hours < 8))
                {
                    // Read the temporary METS file, and use that to build the qc_item
                    qc_item = SobekCM_Item_Factory.Get_Item(metsInProcessFile, Current_Object.BibID, Current_Object.VID, null, null, null);
                    qc_item.Source_Directory = Current_Object.Source_Directory;
                }
                else
                {
                    // Just read the normal otherwise ( if we had the ability to deep copy a SobekCM_Item, we could skip this )
                    qc_item = SobekCM_Item_Factory.Get_Item(Current_Object.BibID, Current_Object.VID, null, null, null);
                }

                // Save to the session, so it is easily available for next time
                HttpContext.Current.Session[Current_Object.BibID + "_" + Current_Object.VID + " QC Work"] = qc_item;
            }

            // If no QC item, this is an error
            if (qc_item == null)
            {
                throw new ApplicationException("Unable to retrieve the item for Quality Control in QC_ItemViewer.Constructor");
            }

            // Get the default QC profile
            qc_profile = QualityControl_Configuration.Default_Profile;

            title = "Quality Control";

            // If this was a post-back keep the required height and width for the qc area
            allThumbnailsOuterDiv1Width = -1;
            allThumbnailsOuterDiv1Height = -1;
            string temp_width = HttpContext.Current.Request.Form["QC_window_width"] ?? String.Empty;
            string temp_height = HttpContext.Current.Request.Form["QC_window_height"] ?? String.Empty;

            if ((temp_width.Length > 0) && (temp_height.Length > 0))
            {
                // Parse the values and save to the session
                if (Int32.TryParse(temp_width, out allThumbnailsOuterDiv1Width))
                    HttpContext.Current.Session["QC_AllThumbnailsWidth"] = allThumbnailsOuterDiv1Width;
                if (Int32.TryParse(temp_height, out allThumbnailsOuterDiv1Height))
                    HttpContext.Current.Session["QC_AllThumbnailsHeight"] = allThumbnailsOuterDiv1Height;

            }
            else
            {
                object session_width = HttpContext.Current.Session["QC_AllThumbnailsWidth"];
                if (session_width != null)
                    allThumbnailsOuterDiv1Width = (int) session_width;
                object session_height = HttpContext.Current.Session["QC_AllThumbnailsHeight"];
                if (session_height != null)
                    allThumbnailsOuterDiv1Height = (int) session_height;
            }

            // See if there were hidden requests
            hidden_request = HttpContext.Current.Request.Form["QC_behaviors_request"] ?? String.Empty;
            hidden_main_thumbnail = HttpContext.Current.Request.Form["Main_Thumbnail_File"] ?? String.Empty;
            hidden_move_relative_position = HttpContext.Current.Request.Form["QC_move_relative_position"] ?? String.Empty;
            hidden_move_destination_fileName = HttpContext.Current.Request.Form["QC_move_destination"] ?? String.Empty;
            autonumber_number_system = HttpContext.Current.Request.Form["Autonumber_number_system"] ?? String.Empty;
            string temp = HttpContext.Current.Request.Form["autonumber_mode_from_form"] ?? "0";
            Int32.TryParse(temp, out autonumber_mode_from_form);
            autonumber_text_only = HttpContext.Current.Request.Form["Autonumber_text_without_number"] ?? String.Empty;
            autonumber_number_only = HttpContext.Current.Request.Form["Autonumber_number_only"] ?? String.Empty;
            autonumber_number_system = HttpContext.Current.Request.Form["Autonumber_number_system"] ?? String.Empty;
            hidden_autonumber_filename = HttpContext.Current.Request.Form["Autonumber_last_filename"] ?? String.Empty;
            temp = HttpContext.Current.Request.Form["QC_sortable_option"] ?? "-1";
            if (Int32.TryParse(temp, out makeSortable) && (makeSortable > 0) && (makeSortable <= 3))
            {
                CurrentUser.Add_Setting("QC_ItemViewer:SortableMode",makeSortable);
            }
            temp = HttpContext.Current.Request.Form["QC_autonumber_option"] ?? "-1";
            if ((Int32.TryParse(temp, out autonumber_mode)) && ( autonumber_mode >= 0 ) && ( autonumber_mode <= 2 ))
            {
                CurrentUser.Add_Setting("QC_ItemViewer:AutonumberingMode", autonumber_mode);
            }

            //Get any notes/comments entered by the user
            notes = HttpContext.Current.Request.Form["txtComments"] ?? String.Empty;

            if (!(Int32.TryParse(HttpContext.Current.Request.Form["QC_Sortable"], out makeSortable))) makeSortable = 3;
            // If the hidden move relative position is BEFORE, it is before the very first page
            if (hidden_move_relative_position == "Before")
                hidden_move_destination_fileName = "[BEFORE FIRST]";

            try
            {

                //Call the JavaScript autosave function based on the option selected
                bool autosaveCacheValue = true;
                bool autosaveCache = false;

                //Conversion result of autosaveCacheValue(conversion successful or not) saved in autosaveCache

                if (HttpContext.Current.Session["autosave_option"] != null)
                    autosaveCache = bool.TryParse(HttpContext.Current.Session["autosave_option"].ToString(), out autosaveCacheValue);
                bool convert = bool.TryParse(HttpContext.Current.Request.Form["Autosave_Option"], out autosave_option);
                if (!convert && !autosaveCache)
                {
                    autosave_option = true;
                }
                else if (!convert && autosaveCache)
                {
                    autosave_option = autosaveCacheValue;
                }

                else
                {
                    HttpContext.Current.Session["autosave_option"] = autosave_option;
                }
            }
            catch (Exception e)
            {
                throw new ApplicationException("Error retrieving auto save option. " + e.Message);
            }

            // Check for a previously set main thumbnail, or one from the requesting form
            if (!String.IsNullOrEmpty(hidden_main_thumbnail))
            {
                HttpContext.Current.Session["main_thumbnail_" + qc_item.BibID + "_" + qc_item.VID] = hidden_main_thumbnail;
            }
            else if (HttpContext.Current.Session["main_thumbnail_" + qc_item.BibID + "_" + qc_item.VID] == null )
            {
                hidden_main_thumbnail = qc_item.Behaviors.Main_Thumbnail.Replace("thm.jpg", "");
                HttpContext.Current.Session["main_thumbnail_" + qc_item.BibID + "_" + qc_item.VID] = hidden_main_thumbnail;
            }
            else
            {
                hidden_main_thumbnail = HttpContext.Current.Session["main_thumbnail_" + qc_item.BibID + "_" + qc_item.VID].ToString();
            }

            //Get the list of associated errors for this item from the database
            int itemID = Resource_Object.Database.SobekCM_Database.Get_ItemID(Current_Object.BibID, Current_Object.VID);
            Get_QC_Errors(itemID);

            // Perform any requested actions
            switch (hidden_request)
            {
                case "autosave":
                case "save":
                case "complete":
                    //Save the current time
                    HttpContext.Current.Session["QC_timeUpdated"] = DateTime.Now.ToString("hh:mm tt");

                    // Read the data from the http form, perform all requests, and
                    // update the qc_item (also updates the session and temporary files)
                    // Save this updated information in the temporary folder's METS file for reading later if necessary.
                    if ((Save_From_Form_Request_To_Item(String.Empty, String.Empty)) && (( hidden_request == "save" ) || ( hidden_request == "complete")))
                    {
                        // If the user selected SAVE or COMPLETE, roll out the new version
                        Move_Temp_Changes_To_Production();

                        // Redirect differently depending on SAVE or COMPLETE
                        if (hidden_request == "save")
                        {
                            // Forward back to the QC form
                            HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl, false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            CurrentMode.Request_Completed = true;
                        }
                        else if (hidden_request == "complete")
                        {
                            // Forward to the item
                            CurrentMode.ViewerCode = String.Empty;
                            CurrentMode.Redirect();
                        }
                    }
                    break;

                case "cancel":
                    Cancel_Current_QC();

                    // Forward back to the default item view
                    CurrentMode.ViewerCode = String.Empty;
                    CurrentMode.Redirect();
                    break;

                case "clear_pagination":
                    ClearPagination();
                    HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl, false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    CurrentMode.Request_Completed = true;
                    break;

                case "clear_reorder":
                    Clear_Pagination_And_Reorder_Pages();
                    HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl, false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    CurrentMode.Request_Completed = true;
                    break;

                case "save_error":
                    string error_code = HttpContext.Current.Request.Form["QC_error_number"] ?? String.Empty;
                    string affected_page_index = HttpContext.Current.Request.Form["QC_affected_file"] ?? String.Empty;
                    SaveQcError(itemID,error_code, affected_page_index);
                    break;

                case "delete_page":
                    // Read the data from the http form, perform all requests, and
                    // update the qc_item (also updates the session and temporary files)
                    string filename_to_delete = HttpContext.Current.Request.Form["QC_affected_file"] ?? String.Empty;
                    if (Save_From_Form_Request_To_Item(String.Empty, filename_to_delete))
                    {
                        Delete_Resource_File(filename_to_delete);
                    }

                    // Since we deleted a page, we need to roll out our new version
                    Move_Temp_Changes_To_Production();

                    HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl, false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    CurrentMode.Request_Completed = true;
                    break;

                case "delete_selected_pages":
                    // Read the data from the http form, perform all requests, and
                    // update the qc_item (also updates the session and temporary files)
                    List<QC_Viewer_Page_Division_Info> selected_page_div_from_form;
                    if (Save_From_Form_Request_To_Item(String.Empty, String.Empty, out selected_page_div_from_form))
                    {
                        foreach (QC_Viewer_Page_Division_Info thisPage in selected_page_div_from_form)
                        {
                            Delete_Resource_File(thisPage.METS_StructMap_Page_Node.Files[0].File_Name_Sans_Extension);
                        }
                    }

                    // Since we deleted a page, we need to roll out our new version
                    Move_Temp_Changes_To_Production();

                    HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl, false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    CurrentMode.Request_Completed = true;
                    break;

                case "move_selected_pages":
                    // Read the data from the http form, perform all requests, and
                    // update the qc_item (also updates the session and temporary files)
                    Save_From_Form_Request_To_Item(hidden_move_destination_fileName, String.Empty);

                    HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl, false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    CurrentMode.Request_Completed = true;
                    break;
            }
        }
        /// <summary> Constructor for a new instance of the Edit_Group_Behaviors_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Current_Item"> Individual digital resource to be edited by the user </param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Edit_Group_Behaviors_MySobekViewer(User_Object User, SobekCM_Navigation_Object Current_Mode, SobekCM_Item Current_Item, Aggregation_Code_Manager Code_Manager, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Edit_Group_Behaviors_MySobekViewer.Constructor", String.Empty);

               currentMode = Current_Mode;
               item = Current_Item;

               // If the user cannot edit this item, go back
               if (!user.Can_Edit_This_Item(item))
               {
               currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
               currentMode.Redirect();
               return;
               }

               const string TEMPLATE_CODE = "groupbehaviors";
               template = Cached_Data_Manager.Retrieve_Template(TEMPLATE_CODE, Tracer);
               if (template != null)
               {
               Tracer.Add_Trace("Edit_Group_Behaviors_MySobekViewer.Constructor", "Found template in cache");
               }
               else
               {
               Tracer.Add_Trace("Edit_Group_Behaviors_MySobekViewer.Constructor", "Reading template file");

               // Read this template
               Template_XML_Reader reader = new Template_XML_Reader();
               template = new Template();
               reader.Read_XML(SobekCM_Library_Settings.Base_MySobek_Directory + "templates\\defaults\\" + TEMPLATE_CODE + ".xml", template, true);

               // Add the current codes to this template
               template.Add_Codes(Code_Manager);

               // Save this into the cache
               Cached_Data_Manager.Store_Template(TEMPLATE_CODE, template, Tracer);
               }

               // See if there was a hidden request
               string hidden_request = HttpContext.Current.Request.Form["behaviors_request"] ?? String.Empty;

               // If this was a cancel request do that
               if (hidden_request == "cancel")
               {
               currentMode.Mode = Display_Mode_Enum.Item_Display;
               currentMode.Redirect();
               }
               else if (hidden_request == "save")
               {
               // Save these changes to bib
               template.Save_To_Bib(item, user, 1);

               // Save the group title
               SobekCM_Database.Update_Item_Group(item.BibID, item.Behaviors.GroupTitle, item.Bib_Info.SortSafeTitle(item.Behaviors.GroupTitle, true), String.Empty, item.Behaviors.Primary_Identifier.Type, item.Behaviors.Primary_Identifier.Identifier );

               // Save the interfaces to the group item as well
               SobekCM_Database.Save_Item_Group_Web_Skins(item.Web.GroupID, item );

               // Store on the caches (to replace the other)
               Cached_Data_Manager.Remove_Digital_Resource_Objects(item.BibID, Tracer);

               // Forward
               currentMode.Mode = Display_Mode_Enum.Item_Display;
               currentMode.Redirect();
               }
        }
        /// <summary> Constructor for a new instance of the Contact_HtmlSubwriter class </summary>
        /// <param name="Last_Mode"> URL for the last mode this user was in before selecting contact us</param>
        /// <param name="UserHistoryRequestInfo"> Some history and user information to include in the final email </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
        public Contact_HtmlSubwriter(string Last_Mode, string UserHistoryRequestInfo, SobekCM_Navigation_Object Current_Mode, Item_Aggregation Hierarchy_Object)
        {
            // Save the parameters
            lastMode = Last_Mode;
            userHistoryRequestInfo = UserHistoryRequestInfo;
            currentMode = Current_Mode;
            this.Current_Aggregation = Hierarchy_Object;

            // If this is a post back, send email
            if (HttpContext.Current.Request.Form["item_action"] == null) return;

            string action = HttpContext.Current.Request.Form["item_action"];
            if (action == "email")
            {
                string notes = HttpContext.Current.Request.Form["notesTextBox"].Trim();
                string subject = HttpContext.Current.Request.Form["subjectTextBox"].Trim();
                string message_from = SobekCM_Library_Settings.System_Email;
                string email = HttpContext.Current.Request.Form["emailTextBox"].Trim();
                string name = HttpContext.Current.Request.Form["nameTextBox"].Trim();

                if ((notes.Length > 0) || (subject.Length > 0))
                {
                    // Create the mail message
                    if (email.Length > 0)
                    {
                        message_from = email;
                    }

                    // Start the body
                    StringBuilder builder = new StringBuilder(1000);
                    builder.Append(notes + "\n\n\n\n");
                    builder.Append("The following information is collected to allow us better serve your needs.\n\n");
                    builder.Append("PERSONAL INFORMATION\n");
                    builder.Append("\tName:\t\t\t\t" + name + "\n");
                    builder.Append("\tEmail:\t\t\t" + email + "\n");
                    builder.Append(userHistoryRequestInfo);
                    string email_body = builder.ToString();

                    try
                    {
                        MailMessage myMail = new MailMessage(message_from, base.Current_Aggregation.Contact_Email.Replace(";", ","))
                                                 {
                                                     Subject =subject + "  [" + currentMode.SobekCM_Instance_Abbreviation +" Submission]",
                                                     Body = email_body
                                                 };
                        // Mail this
                        SmtpClient client = new SmtpClient("smtp.ufl.edu");
                        client.Send(myMail);

                        // Log this
                        string sender = message_from;
                        if (name.Length > 0)
                            sender = name + " ( " + message_from + " )";
                        SobekCM_Database.Log_Sent_Email(sender, base.Current_Aggregation.Contact_Email.Replace(";", ","), subject + "  [" + currentMode.SobekCM_Instance_Abbreviation + " Submission]", email_body, false, true, -1);

                        // Send back to the home for this collection, sub, or group
                        Current_Mode.Mode = Display_Mode_Enum.Contact_Sent;
                        Current_Mode.Redirect();
                        return;
                    }
                    catch
                    {
                        bool email_error = SobekCM_Database.Send_Database_Email(base.Current_Aggregation.Contact_Email.Replace(";", ","), subject + "  [" + currentMode.SobekCM_Instance_Abbreviation + " Submission]", email_body, false, true, -1, -1 );

                        // Send back to the home for this collection, sub, or group
                        if (email_error)
                        {
                            HttpContext.Current.Response.Redirect(SobekCM_Library_Settings.System_Error_URL, false);
                            HttpContext.Current.ApplicationInstance.CompleteRequest();
                            return;
                        }
                        else
                        {
                            // Send back to the home for this collection, sub, or group
                            Current_Mode.Mode = Display_Mode_Enum.Contact_Sent;
                            Current_Mode.Redirect();
                            return;
                        }
                    }
                }
            }
        }
        /// <summary> Constructor for a new instance of the Skins_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="CurrentMode"> Mode / navigation information for the current request</param>
        /// <param name="Web_Skin_Collection"> Contains the collection of all the default skins and the data to create any additional skins on request</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling an edit or new html skin is handled here in the constructor </remarks>
        public Skins_AdminViewer(User_Object User, SobekCM_Navigation_Object CurrentMode, SobekCM_Skin_Collection Web_Skin_Collection, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Skins_AdminViewer.Constructor", String.Empty);

            // Save the mode and settings  here
            currentMode = CurrentMode;
            skinCollection = Web_Skin_Collection;

            // Set action message to nothing to start
            actionMessage = String.Empty;

            // If the user cannot edit this, go back
            if ((!user.Is_System_Admin) && ( !user.Is_Portal_Admin ))
            {
                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // If this is a postback, handle any events first
            if (currentMode.isPostBack)
            {
                try
                {
                    // Pull the standard values
                    NameValueCollection form = HttpContext.Current.Request.Form;

                    string reset_value = form["admin_interface_reset"].ToLower();
                    string save_value = form["admin_interface_tosave"].ToUpper().Trim();
                    string delete_value = form["admin_interface_delete"].ToUpper().Trim();
                    string new_interface_code = form["admin_interface_code"].ToUpper().Trim();

                    // Was this a reset request?
                    if (reset_value.Length > 0)
                    {
                        Tracer.Add_Trace("Skins_AdminViewer.Constructor", "Reset html skin '" + reset_value + "'");

                        if (Web_Skin_Collection.Remove(reset_value))
                        {
                            actionMessage = "Removed skin <i>" + reset_value.ToUpper() + "</i> from the semi-permanent skin collection";
                        }
                        else
                        {
                            int values_cleared = Cached_Data_Manager.Remove_Skin(reset_value, Tracer);

                            if (values_cleared == 0)
                            {
                                actionMessage = "Html skin <i>" + reset_value.ToUpper() + "</i> was not in the application cache";
                            }
                            else
                            {
                                actionMessage = "Removed " + values_cleared + " values from the cache for <i>" + reset_value.ToUpper() + "</i>";
                            }
                        }

                    }
                    else if (delete_value.Length > 0)
                    {
                        if (user.Is_System_Admin)
                        {
                            Tracer.Add_Trace("Skins_AdminViewer.Constructor", "Delete skin '" + delete_value + "' from the database");

                            // Delete from the database
                            if (SobekCM_Database.Delete_Web_Skin(delete_value, false, Tracer))
                            {
                                // Set the deleted wordmark message
                                actionMessage = "Deleted web skin <i>" + delete_value + "</i>";

                                // Remove this web skin from the collection
                                SobekCM_Skin_Collection_Builder.Populate_Default_Skins(Web_Skin_Collection, Tracer);
                            }
                            else
                            {
                                // Report the error
                                if (SobekCM_Database.Last_Exception == null)
                                {
                                    actionMessage = "Unable to delete web skin <i>" + delete_value + "</i> since it is linked to an item, aggregation, or portal";
                                }
                                else
                                {
                                    actionMessage = "Unknown error while deleting web skin <i>" + delete_value + "</i>";
                                }
                            }
                        }
                    }
                    else
                    {
                        // Or.. was this a save request
                        if (save_value.Length > 0)
                        {
                            Tracer.Add_Trace("Skins_AdminViewer.Constructor", "Save html skin '" + save_value + "'");

                            bool override_banner = false;
                            bool override_header = false;
                            bool build_on_launch = false;
                            bool suppress_top_nav = false;
                            bool copycurrent = false;
                            object temp_object;

                            // Was this to save a new interface (from the main page) or edit an existing (from the popup form)?
                            if (save_value == new_interface_code)
                            {
                                string new_base_code = form["admin_interface_basecode"].ToUpper().Trim();
                                string new_banner_link = form["admin_interface_link"].Trim();
                                string new_notes = form["admin_interface_notes"].Trim();

                                temp_object = form["admin_interface_banner_override"];
                                if (temp_object != null)
                                {
                                    override_banner = true;
                                }

                                temp_object = form["admin_interface_header_override"];
                                if (temp_object != null)
                                {
                                    override_header = true;
                                }

                                temp_object = form["admin_interface_buildlaunch"];
                                if (temp_object != null)
                                {
                                    build_on_launch = true;
                                }

                                temp_object = form["admin_interface_top_nav"];
                                if (temp_object != null)
                                {
                                    suppress_top_nav = true;
                                }

                                temp_object = form["admin_interface_copycurrent"];
                                if (temp_object != null)
                                {
                                    copycurrent = true;
                                }

                                // Save this new interface
                                if (SobekCM_Database.Save_Web_Skin(save_value, new_base_code, override_banner, override_header, new_banner_link, new_notes, build_on_launch, suppress_top_nav, Tracer))
                                {
                                    // Ensure a folder exists for this, otherwise create one
                                    try
                                    {
                                        string folder = SobekCM_Library_Settings.Base_Design_Location + "skins/" + save_value.ToLower();
                                        if (!Directory.Exists(folder))
                                        {
                                            // Create this directory and the necessary subdirectories
                                            Directory.CreateDirectory(folder);

                                            // Create a default stylesheet
                                            StreamWriter writer = new StreamWriter(folder + "\\" + save_value.ToLower() + ".css");
                                            writer.WriteLine("/*  Skin-specific stylesheet used to override values from the base stylesheets */");
                                            writer.WriteLine();
                                            writer.WriteLine();
                                            writer.Flush();
                                            writer.Close();

                                            // Create the html subdirectory
                                            Directory.CreateDirectory(folder + "/html");

                                            // Do the rest differently depending on whether we should copy the current files
                                            if (!copycurrent)
                                            {
                                                // Write the default header file
                                                writer = new StreamWriter(folder + "\\html\\header.html");
                                                writer.WriteLine("<div id=\"container-inner\">");
                                                writer.WriteLine();
                                                writer.WriteLine("<!-- Add the standard header buttons -->");
                                                writer.WriteLine("<div style=\"width: 100%; background-color: #eeeeee; color: Black; height:30px;\">");
                                                writer.WriteLine("<%BREADCRUMBS%>");
                                                writer.WriteLine("<div style=\"float: right\"><%MYSOBEK%></div>");
                                                writer.WriteLine("</div>");
                                                writer.WriteLine();
                                                writer.WriteLine("<%BANNER%>");
                                                writer.WriteLine();
                                                writer.WriteLine("<div id=\"pagecontainer\">");
                                                writer.WriteLine();
                                                writer.WriteLine("<!-- Blankets out the rest of the web form when a pop-up form is envoked -->");
                                                writer.WriteLine("<div id=\"blanket_outer\" style=\"display:none;\"></div>");
                                                writer.Flush();
                                                writer.Close();

                                                // Write the default header_item file
                                                writer = new StreamWriter(folder + "/html/header_item.html");
                                                writer.WriteLine("<!-- Blankets out the rest of the web form when a pop-up form is envoked -->");
                                                writer.WriteLine("<div id=\"blanket_outer\" style=\"display:none;\"></div>");
                                                writer.WriteLine();
                                                writer.WriteLine("<!-- Add the standard header buttons -->");
                                                writer.WriteLine("<div style=\"width: 100%; background-color: #eeeeee; color: Black; height:30px;\">");
                                                writer.WriteLine("<%BREADCRUMBS%>");
                                                writer.WriteLine("<div style=\"float: right\"><%MYSOBEK%></div>");
                                                writer.WriteLine("</div>");
                                                writer.WriteLine();
                                                writer.WriteLine("<%BANNER%>");
                                                writer.Flush();
                                                writer.Close();

                                                // Write the default footer file
                                                writer = new StreamWriter(folder + "/html/footer.html");
                                                writer.WriteLine("</div> <!-- END PAGE CONTAINER DIV -->");
                                                writer.WriteLine();
                                                writer.WriteLine("<!-- Add most the standard footer buttons -->");
                                                writer.WriteLine("<center>");
                                                writer.WriteLine("<a href=\"<%BASEURL%>contact<%?URLOPTS%>\">Contact Us</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>preferences<%?URLOPTS%>\">Preferences</a> | ");
                                                writer.WriteLine("<a href=\"http://ufdc.ufl.edu/sobekcm\">Technical Aspects</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>stats<%?URLOPTS%>\">Statistics</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>internal<%?URLOPTS%>\">Internal</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>admin<%?URLOPTS%>\">Admin</a>");
                                                writer.WriteLine("</center>");
                                                writer.WriteLine("<br />");
                                                writer.WriteLine("<br />");
                                                writer.WriteLine("<span style=\"color: Gray; font-size: 0.8em;\">");
                                                writer.WriteLine("To edit this footer or header, edit header.html or footer.html at:  " + folder + "\\html\\ <br />");
                                                writer.WriteLine("</span>");
                                                writer.WriteLine();
                                                writer.WriteLine("</div> <!-- END CONTAINER INNER -->");
                                                writer.Flush();
                                                writer.Close();

                                                // Write the default footer item file
                                                writer = new StreamWriter(folder + "/html/footer_item.html");
                                                writer.WriteLine("<!-- Add most the standard footer buttons -->");
                                                writer.WriteLine("<center>");
                                                writer.WriteLine("<a href=\"<%BASEURL%>contact<%?URLOPTS%>\">Contact Us</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>preferences<%?URLOPTS%>\">Preferences</a> | ");
                                                writer.WriteLine("<a href=\"http://ufdc.ufl.edu/sobekcm\">Technical Aspects</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>stats<%?URLOPTS%>\">Statistics</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>internal<%?URLOPTS%>\">Internal</a> | ");
                                                writer.WriteLine("<a href=\"<%BASEURL%>admin<%?URLOPTS%>\">Admin</a>");
                                                writer.WriteLine("</center>");
                                                writer.WriteLine("<br />");
                                                writer.WriteLine("<br />");
                                                writer.WriteLine("<span style=\"color: Gray; font-size: 0.8em;\">");
                                                writer.WriteLine("To edit this footer or header, edit header.html or footer.html at:  " + folder + "\\html\\ <br />");
                                                writer.WriteLine("</span>");
                                                writer.Flush();
                                                writer.Close();
                                            }
                                            else
                                            {
                                                // Copy the web skin information over?
                                                string current_web_skin = currentMode.Skin;
                                                string current_web_folder = SobekCM_Library_Settings.Base_Design_Location + "skins/" + current_web_skin;
                                                copy_entire_folder(current_web_folder, folder);
                                                //if (File.Exists(current_web_folder + "\\" + current_web_skin + ".css"))
                                                //{
                                                //    File.Copy(current_web_folder + "\\" + current_web_skin + ".css", folder + "\\" + new_interface_code + ".css", true );
                                                //}
                                                //if (File.Exists(current_web_folder + "\\html\\header.html"))
                                                //{
                                                //    File.Copy(current_web_folder + "\\html\\header.html", folder + "\\html\\header.html");
                                                //}
                                                //if (File.Exists(current_web_folder + "\\html\\header_item.html"))
                                                //{
                                                //    File.Copy(current_web_folder + "\\html\\header_item.html", folder + "\\html\\header_item.html");
                                                //}
                                                //if (File.Exists(current_web_folder + "\\html\\footer.html"))
                                                //{
                                                //    File.Copy(current_web_folder + "\\html\\footer.html", folder + "\\html\\footer.html");
                                                //}
                                                //if (File.Exists(current_web_folder + "\\html\\footer_item.html"))
                                                //{
                                                //    File.Copy(current_web_folder + "\\html\\footer_item.html", folder + "\\html\\footer_item.html");
                                                //}
                                                if (File.Exists(folder + "\\" + current_web_skin + ".css"))
                                                {
                                                    if (File.Exists(folder + "\\" + new_interface_code + ".css"))
                                                        File.Delete(folder + "\\" + new_interface_code + ".css");
                                                    File.Move( folder + "\\" + current_web_skin + ".css", folder + "\\" + new_interface_code + ".css" );
                                                }
                                            }

                                            // Irregardless of the user's choice on whether to copy the current skin, if there is NO base skin
                                            // provided and the folder does not exist, then we'll copy over the base skin type of stuff, such
                                            // as buttons, tabs, etc...
                                            if (new_base_code.Length == 0)
                                            {
                                                // What is the current base skin folder then?
                                                string base_skin_folder = SobekCM_Library_Settings.Base_Design_Location + "skins/" + currentMode.Base_Skin;
                                                copy_entire_folder(base_skin_folder + "/buttons", folder + "/buttons");
                                                copy_entire_folder(base_skin_folder + "/tabs", folder + "/tabs");
                                                copy_entire_folder(base_skin_folder + "/zoom_controls", folder + "/zoom_controls");
                                            }

                                        }
                                    }
                                    catch (Exception )
                                    {
                                        actionMessage = "Error creating some of the files for the new web skin";
                                    }

                                    // Reload the list of all skins from the database, to include this new skin
                                    lock (skinCollection)
                                    {
                                        SobekCM_Skin_Collection_Builder.Populate_Default_Skins(skinCollection, Tracer);
                                    }
                                    if (String.IsNullOrEmpty(actionMessage))
                                    {
                                        actionMessage = "Saved new html skin <i>" + save_value + "</i>";
                                    }
                                }
                                else
                                {
                                    actionMessage = "Unable to save new html skin <i>" + save_value + "</i>";
                                }

                                // Try to create the directory
                                try
                                {
                                    if (!Directory.Exists(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value))
                                    {
                                        Directory.CreateDirectory(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value);
                                    }
                                    if (!Directory.Exists(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\html"))
                                    {
                                        Directory.CreateDirectory(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\html");
                                    }
                                    if (new_base_code.Length == 0)
                                    {
                                        if (!Directory.Exists(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\buttons"))
                                        {
                                            Directory.CreateDirectory(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\buttons");
                                        }
                                        if (!Directory.Exists(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\tabs"))
                                        {
                                            Directory.CreateDirectory(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\tabs");
                                        }
                                        if (!Directory.Exists(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\zoom_controls"))
                                        {
                                            Directory.CreateDirectory(SobekCM_Library_Settings.Base_Design_Location + "skins\\" + save_value + "\\zoom_controls");
                                        }
                                    }
                                }
                                catch (Exception)
                                {
                                    actionMessage = "Error creating all the necessary folders";
                                }
                            }
                            else
                            {
                                string edit_base_code = form["form_interface_basecode"].ToUpper().Trim();
                                string edit_banner_link = form["form_interface_link"].Trim();
                                string edit_notes = form["form_interface_notes"].Trim();

                                temp_object = form["form_interface_banner_override"];
                                if (temp_object != null)
                                {
                                    override_banner = true;
                                }

                                temp_object = form["form_interface_header_override"];
                                if (temp_object != null)
                                {
                                    override_header = true;
                                }

                                temp_object = form["form_interface_buildlaunch"];
                                if (temp_object != null)
                                {
                                    build_on_launch = true;
                                }

                                temp_object = form["form_interface_top_nav"];
                                if (temp_object != null)
                                {
                                    suppress_top_nav = true;
                                }

                                // Save this existing interface
                                if (SobekCM_Database.Save_Web_Skin(save_value, edit_base_code, override_banner, override_header, edit_banner_link, edit_notes, build_on_launch, suppress_top_nav, Tracer))
                                {
                                    lock (skinCollection)
                                    {
                                        SobekCM_Skin_Collection_Builder.Populate_Default_Skins(skinCollection, Tracer);
                                    }
                                    Cached_Data_Manager.Remove_Skin(save_value, Tracer);

                                    actionMessage = "Edited existing html skin <i>" + save_value + "</i>";
                                }
                                else
                                {
                                    actionMessage = "Unable to edit existing html skin <i>" + save_value + "</i>";
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    actionMessage = "Unknown error caught while handing your request.";
                }
            }
        }
        /// <summary> Constructor for a new instance of the Admin_HtmlSubwriter class </summary>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="All_Items_Lookup"> Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Aggregation_Aliases"> List of all existing aliases for existing aggregations </param>
        /// <param name="Web_Skin_Collection"> Collection of all the web skins </param>
        /// <param name="Current_User"> Currently logged on user </param>
        /// <param name="Icon_Table"> Dictionary of all the wordmark/icons which can be tagged to the items </param>
        /// <param name="IP_Restrictions"> List of all IP Restriction ranges in use by this digital library </param>
        /// <param name="URL_Portals"> List of all web portals into this system </param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the home page are organized </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public Admin_HtmlSubwriter(  Aggregation_Code_Manager Code_Manager,
                                     Item_Lookup_Object All_Items_Lookup,
                                     Item_Aggregation Hierarchy_Object,
                                     SobekCM_Skin_Object HTML_Skin,
                                     Language_Support_Info Translator,
                                     SobekCM_Navigation_Object Current_Mode,
                                     Dictionary<string,string> Aggregation_Aliases,
                                     SobekCM_Skin_Collection Web_Skin_Collection,
                                     User_Object Current_User,
                                     IP_Restriction_Ranges IP_Restrictions,
                                     Dictionary<string, Wordmark_Icon> Icon_Table,
                                     Portal_List URL_Portals,
                                     List<Thematic_Heading> Thematic_Headings,
                                     Custom_Tracer Tracer )
        {
            Tracer.Add_Trace("Admin_HtmlSubwriter.Constructor", "Saving values and geting user object back from the session");

            codeManager = Code_Manager;
            itemList = All_Items_Lookup;
            htmlSkin = HTML_Skin;
            translator = Translator;
            currentCollection = Hierarchy_Object;
            user = Current_User;
            ipRestrictions = IP_Restrictions;
            iconTable = Icon_Table;

            // All Admin pages require a user being logged on
            if (Current_User == null)
            {
                Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Logon;
                Current_Mode.My_Sobek_SubMode = String.Empty;
                Current_Mode.Redirect();
                return;
            }

            // If the user is not an admin, and admin was selected, reroute this
            if ((!Current_User.Is_System_Admin) && (!Current_User.Is_Portal_Admin) && (Current_Mode.Admin_Type != Admin_Type_Enum.Aggregation_Single))
            {
                Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                Current_Mode.My_Sobek_SubMode = String.Empty;
                Current_Mode.Redirect();
                return;
            }

            Tracer.Add_Trace("Admin_HtmlSubwriter.Constructor", "Building the my sobek viewer object");
            switch (Current_Mode.Admin_Type)
            {
                case Admin_Type_Enum.Aggregation_Single:
                    adminViewer = new Aggregation_Single_AdminViewer(user, Current_Mode, codeManager, Thematic_Headings, Web_Skin_Collection, Tracer);
                    break;

                case Admin_Type_Enum.Home:
                    adminViewer = new Home_AdminViewer(user, Current_Mode, Tracer);
                    break;

                case Admin_Type_Enum.Builder_Status:
                    adminViewer = new Builder_AdminViewer(user, Current_Mode);
                    break;

                case Admin_Type_Enum.Skins:
                    adminViewer = new Skins_AdminViewer(user, Current_Mode, Web_Skin_Collection, Tracer);
                    break;

                case Admin_Type_Enum.Aliases:
                    adminViewer = new Aliases_AdminViewer(user, Current_Mode, Aggregation_Aliases, Code_Manager, Tracer);
                    break;

                case Admin_Type_Enum.Wordmarks:
                    adminViewer = new Wordmarks_AdminViewer(user, Current_Mode, Tracer);
                    break;

                case Admin_Type_Enum.URL_Portals:
                    adminViewer = new Portals_AdminViewer(user, Current_Mode, URL_Portals, Web_Skin_Collection, Tracer);
                    break;

                case Admin_Type_Enum.Users:
                    adminViewer = new Users_AdminViewer(user, Current_Mode, codeManager, Tracer);
                    break;

                case Admin_Type_Enum.User_Groups:
                    adminViewer = new User_Group_AdminViewer(user, Current_Mode, codeManager, Tracer);
                    break;

                case Admin_Type_Enum.Aggregations_Mgmt:
                    adminViewer = new Aggregations_Mgmt_AdminViewer(user, Current_Mode, codeManager, Thematic_Headings, Tracer);
                    break;

                case Admin_Type_Enum.IP_Restrictions:
                    adminViewer = new IP_Restrictions_AdminViewer(user, Current_Mode, ipRestrictions, Tracer);
                    break;

                case Admin_Type_Enum.Thematic_Headings:
                    adminViewer = new Thematic_Headings_AdminViewer(user, Current_Mode, Thematic_Headings, codeManager, Tracer);
                    break;

                case Admin_Type_Enum.Settings:
                    adminViewer = new Settings_AdminViewer(user, Current_Mode, Tracer);
                    break;

                case Admin_Type_Enum.Default_Metadata:
                    if (Current_Mode.My_Sobek_SubMode.Length > 1)
                    {
                        string project_code = Current_Mode.My_Sobek_SubMode.Substring(1);
                        Tracer.Add_Trace("MySobek_HtmlSubwriter.Constructor", "Checking cache for valid project file");
                        if (user != null)
                        {
                            SobekCM_Item projectObject = Cached_Data_Manager.Retrieve_Project(user.UserID, project_code, Tracer);
                            if (projectObject != null)
                            {
                                Tracer.Add_Trace("MySobek_HtmlSubwriter.Constructor", "Valid default metadata set found in cache");
                                adminViewer = new Edit_Item_Metadata_MySobekViewer(user, Current_Mode, itemList, projectObject, codeManager, iconTable, htmlSkin, null, null, Tracer);
                            }
                            else
                            {
                                if (SobekCM_Database.Get_All_Template_DefaultMetadatas(Tracer).Tables[0].Select("MetadataCode='" + project_code + "'").Length > 0)
                                {
                                    Tracer.Add_Trace("MySobek_HtmlSubwriter.Constructor", "Building default metadata set from (possible) PMETS");
                                    string pmets_file = SobekCM_Library_Settings.Base_MySobek_Directory + "projects\\" + Current_Mode.My_Sobek_SubMode.Substring(1) + ".pmets";
                                    SobekCM_Item pmets_item = File.Exists(pmets_file) ? SobekCM_Item.Read_METS(pmets_file) : new SobekCM_Item();
                                    pmets_item.Bib_Info.Main_Title.Title = "Default metadata set for '" + project_code + "'";
                                    pmets_item.Bib_Info.SobekCM_Type = TypeOfResource_SobekCM_Enum.Project;
                                    pmets_item.BibID = project_code.ToUpper();
                                    pmets_item.VID = "00001";
                                    pmets_item.Source_Directory = SobekCM_Library_Settings.Base_MySobek_Directory +  "projects\\";

                                    Tracer.Add_Trace("MySobek_HtmlSubwriter.Constructor", "Adding project file to cache");

                                    Cached_Data_Manager.Store_Project(user.UserID, project_code, pmets_item, Tracer);

                                    adminViewer = new Edit_Item_Metadata_MySobekViewer(user, Current_Mode, itemList, pmets_item, codeManager, iconTable, htmlSkin, null, null, Tracer);
                                }
                            }
                        }
                    }

                    if (adminViewer == null)
                        adminViewer = new Default_Metadata_AdminViewer(user, Current_Mode, Tracer);
                    break;
            }

            // Pass in the navigation and translator information
            adminViewer.CurrentMode = Current_Mode;
            adminViewer.Translator = translator;
        }
        /// <summary> Constructor for a new instance of the Aggregations_Mgmt_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="CurrentMode"> Mode / navigation information for the current request</param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the home page are organized </param>       
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling an edit or new aggregation is handled here in the constructor </remarks>
        public Aggregations_Mgmt_AdminViewer(User_Object User, SobekCM_Navigation_Object CurrentMode, Aggregation_Code_Manager Code_Manager, List<Thematic_Heading> Thematic_Headings, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Aggregations_Mgmt_AdminViewer.Constructor", String.Empty);

            codeManager = Code_Manager;
            currentMode = CurrentMode;
            thematicHeadings = Thematic_Headings;

            // Set some defaults
            actionMessage = String.Empty;
            enteredCode = String.Empty;
            enteredParent = String.Empty;
            enteredType = String.Empty;
            enteredShortname = String.Empty;
            enteredName = String.Empty;
            enteredDescription = String.Empty;
            enteredIsActive = false;
            enteredIsHidden = false;

            // If the user cannot edit this, go back
            if (( user == null ) || ((!user.Is_System_Admin) && ( !user.Is_Portal_Admin )))
            {
                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // If this is a postback, handle any events first
            if (currentMode.isPostBack)
            {
                try
                {
                    // Pull the standard values
                    NameValueCollection form = HttpContext.Current.Request.Form;

                    string save_value = form["admin_aggr_tosave"].ToUpper().Trim();
                    string new_aggregation_code = String.Empty;
                    if ( form["admin_aggr_code"] != null )
                        new_aggregation_code = form["admin_aggr_code"].ToUpper().Trim();

                    // Check for reset request as well
                    string reset_aggregation_code = String.Empty;
                    if (form["admin_aggr_reset"] != null)
                        reset_aggregation_code = form["admin_aggr_reset"].ToLower().Trim();

                    string delete_aggregation_code = String.Empty;
                    if (form["admin_aggr_delete"] != null)
                        delete_aggregation_code = form["admin_aggr_delete"].ToLower().Trim();

                    // Was this to delete the aggregation?
                    if ( delete_aggregation_code.Length > 0)
                    {
                        string delete_error;
                        int errorCode = SobekCM_Database.Delete_Item_Aggregation(delete_aggregation_code, user.Is_System_Admin, user.Full_Name, Tracer, out delete_error);
                        if (errorCode <= 0)
                        {
                            string delete_folder = SobekCM_Library_Settings.Base_Design_Location + "aggregations\\" + delete_aggregation_code;
                            if (SobekCM_File_Utilities.Delete_Folders_Recursively(delete_folder))
                                actionMessage = "Deleted '" + delete_aggregation_code + "' aggregation<br /><br />Unable to remove aggregation directory<br /><br />Some of the files may be in use";
                            else
                                actionMessage = "Deleted '" + delete_aggregation_code + "' aggregation";
                        }
                        else
                        {
                            actionMessage = delete_error;
                        }

                        // Reload the list of all codes, to include this new one and the new hierarchy
                        lock (codeManager)
                        {
                            SobekCM_Database.Populate_Code_Manager(codeManager, Tracer);
                        }
                    }

                    // If there is a reset request here, purge the aggregation from the cache
                    if (reset_aggregation_code.Length > 0)
                    {
                        Cached_Data_Manager.Remove_Item_Aggregation(reset_aggregation_code, Tracer);
                    }

                    // If there was a save value continue to pull the rest of the data
                    if (save_value.Length > 0)
                    {

                        bool is_active = false;
                        bool is_hidden = true;

                        // Was this to save a new aggregation (from the main page) or edit an existing (from the popup form)?
                        if (save_value == new_aggregation_code)
                        {

                            // Pull the values from the submitted form
                            string new_type = form["admin_aggr_type"];
                            string new_parent = form["admin_aggr_parent"].Trim();
                            string new_name = form["admin_aggr_name"].Trim();
                            string new_shortname = form["admin_aggr_shortname"].Trim();
                            string new_description = form["admin_aggr_desc"].Trim();
                            string new_link = form["admin_aggr_link"].Trim();

                            object temp_object = form["admin_aggr_isactive"];
                            if (temp_object != null)
                            {
                                is_active = true;
                            }

                            temp_object = form["admin_aggr_ishidden"];
                            if (temp_object != null)
                            {
                                is_hidden = false;
                            }

                            // Convert to the integer id for the parent and begin to do checking
                            List<string> errors = new List<string>();
                            int parentid = -1;
                            if (new_parent.Length > 0)
                            {
                                try
                                {
                                    parentid = Convert.ToInt32(new_parent);
                                }
                                catch
                                {
                                    errors.Add("Invalid parent id selected!");
                                }
                            }
                            else
                            {
                                errors.Add("You must select a PARENT for this new aggregation");
                            }

                            // Validate the code
                            if (new_aggregation_code.Length > 20)
                            {
                                errors.Add("New aggregation code must be twenty characters long or less");
                            }
                            else if (new_aggregation_code.Length == 0)
                            {
                                errors.Add("You must enter a CODE for this item aggregation");

                            }
                            else if (codeManager[new_aggregation_code.ToUpper()] != null)
                            {
                                errors.Add("New code must be unique... <i>" + new_aggregation_code + "</i> already exists");
                            }
                            else if (SobekCM_Library_Settings.Reserved_Keywords.Contains(new_aggregation_code.ToLower()))
                            {
                                errors.Add("That code is a system-reserved keyword.  Try a different code.");
                            }

                            // Was there a type and name
                            if (new_type.Length == 0)
                            {
                                errors.Add("You must select a TYPE for this new aggregation");
                            }
                            if (new_description.Length == 0)
                            {
                                errors.Add("You must enter a DESCRIPTION for this new aggregation");
                            }
                            if (new_name.Length == 0)
                            {
                                errors.Add("You must enter a NAME for this new aggregation");
                            }
                            else
                            {
                                if (new_shortname.Length == 0)
                                    new_shortname = new_name;
                            }

                            if (errors.Count > 0)
                            {
                                // Create the error message
                                actionMessage = "ERROR: Invalid entry for new item aggregation<br />";
                                foreach (string error in errors)
                                    actionMessage = actionMessage + "<br />" + error;

                                // Save all the values that were entered
                                enteredCode = new_aggregation_code;
                                enteredDescription = new_description;
                                enteredIsActive = is_active;
                                enteredIsHidden = is_hidden;
                                enteredName = new_name;
                                enteredParent = new_parent;
                                enteredShortname = new_shortname;
                                enteredType = new_type;
                                enteredLink = new_link;
                            }
                            else
                            {
                                // Get the correct type
                                string correct_type = "Collection";
                                switch (new_type)
                                {
                                    case "coll":
                                        correct_type = "Collection";
                                        break;

                                    case "group":
                                        correct_type = "Collection Group";
                                        break;

                                    case "subcoll":
                                        correct_type = "SubCollection";
                                        break;

                                    case "inst":
                                        correct_type = "Institution";
                                        break;

                                    case "exhibit":
                                        correct_type = "Exhibit";
                                        break;

                                    case "subinst":
                                        correct_type = "Institutional Division";
                                        break;
                                }
                                // Make sure inst and subinst start with 'i'
                                if (new_type.IndexOf("inst") >= 0)
                                {
                                    if (new_aggregation_code[0] == 'I')
                                        new_aggregation_code = "i" + new_aggregation_code.Substring(1);
                                    if (new_aggregation_code[0] != 'i')
                                        new_aggregation_code = "i" + new_aggregation_code;
                                }

                                // Get the thematic heading id (no checks here)
                                int thematicHeadingId = -1;
                                if (form["admin_aggr_heading"] != null)
                                    thematicHeadingId = Convert.ToInt32(form["admin_aggr_heading"]);

                                // Try to save the new item aggregation
                                if (SobekCM_Database.Save_Item_Aggregation(new_aggregation_code, new_name, new_shortname, new_description, thematicHeadingId, correct_type, is_active, is_hidden, new_link, parentid, user.Full_Name, Tracer))
                                {
                                    // Ensure a folder exists for this, otherwise create one
                                    try
                                    {
                                        string folder = SobekCM_Library_Settings.Base_Design_Location + "aggregations\\" + new_aggregation_code.ToLower();
                                        if (!Directory.Exists(folder))
                                        {
                                            // Create this directory and all the subdirectories
                                            Directory.CreateDirectory(folder);
                                            Directory.CreateDirectory(folder + "/html");
                                            Directory.CreateDirectory(folder + "/images");
                                            Directory.CreateDirectory(folder + "/html/home");
                                            Directory.CreateDirectory(folder + "/images/buttons");
                                            Directory.CreateDirectory(folder + "/images/banners");

                                            // Create a default home text file
                                            StreamWriter writer = new StreamWriter(folder + "/html/home/text.html");
                                            writer.WriteLine("<br />New collection home page text goes here.<br /><br />To edit this, log on as the aggregation admin and hover over this text to edit it.<br /><br />");
                                            writer.Flush();
                                            writer.Close();

                                            // Copy the default banner and buttons from images
                                            if (File.Exists(SobekCM_Library_Settings.Base_Directory + "default/images/default_button.png"))
                                                File.Copy(SobekCM_Library_Settings.Base_Directory + "default/images/default_button.png", folder + "/images/buttons/coll.png");
                                            if (File.Exists(SobekCM_Library_Settings.Base_Directory + "default/images/default_button.gif"))
                                                File.Copy(SobekCM_Library_Settings.Base_Directory + "default/images/default_button.gif", folder + "/images/buttons/coll.gif");

                                            // Try to create a new custom banner
                                            bool custom_banner_created = false;
                                            // Create the banner with the name of the collection
                                            if (Directory.Exists(SobekCM_Library_Settings.Application_Server_Network + "\\default\\banner_images"))
                                            {
                                                try
                                                {
                                                    string[] banners = Directory.GetFiles(SobekCM_Library_Settings.Application_Server_Network + "\\default\\banner_images", "*.jpg");
                                                    if (banners.Length > 0)
                                                    {
                                                        Random randomizer = new Random();
                                                        string banner_to_use = banners[randomizer.Next(0, banners.Length - 1)];
                                                        Bitmap bitmap = (Bitmap)System.Drawing.Bitmap.FromFile(banner_to_use);

                                                        RectangleF rectf = new RectangleF(30, bitmap.Height - 55, bitmap.Width - 40, 40);
                                                        Graphics g = Graphics.FromImage(bitmap);
                                                        g.SmoothingMode = SmoothingMode.AntiAlias;
                                                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                                        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                                                        g.DrawString(new_name, new Font("Tahoma", 25, FontStyle.Bold), Brushes.Black, rectf);
                                                        g.Flush();

                                                        string new_file = folder + "/images/banners/coll.jpg";
                                                        if (!File.Exists(new_file))
                                                        {
                                                            bitmap.Save(new_file, ImageFormat.Jpeg);
                                                            custom_banner_created = true;
                                                        }
                                                    }
                                                }
                                                catch (Exception ee)
                                                {
                                                    string msg = ee.Message;
                                                }
                                            }

                                            if ((!custom_banner_created) && (!File.Exists(folder + "/images/banners/coll.jpg")))
                                            {
                                                if (File.Exists(SobekCM_Library_Settings.Base_Directory + "default/images/default_banner.jpg"))
                                                    File.Copy(SobekCM_Library_Settings.Base_Directory + "default/images/default_banner.jpg", folder + "/images/banners/coll.jpg");
                                            }

                                            // Now, try to create the item aggregation and write the configuration file
                                            Item_Aggregation itemAggregation = Item_Aggregation_Builder.Get_Item_Aggregation(new_aggregation_code, String.Empty, null, false, false, Tracer);
                                            itemAggregation.Write_Configuration_File(SobekCM_Library_Settings.Base_Design_Location + itemAggregation.ObjDirectory);
                                        }
                                    }
                                    catch
                                    {
                                        actionMessage = "ERROR saving the new item aggregation to the database";
                                    }

                                    // Reload the list of all codes, to include this new one and the new hierarchy
                                    lock (codeManager)
                                    {
                                        SobekCM_Database.Populate_Code_Manager(codeManager, Tracer);
                                    }
                                    if ( !String.IsNullOrEmpty(actionMessage))
                                        actionMessage = "New item aggregation <i>" + new_aggregation_code + "</i> saved successfully";
                                }
                                else
                                {
                                    actionMessage = "ERROR saving the new item aggregation to the database";
                                }
                            }
                        }
                    }
                }
                catch
                {
                    actionMessage = "General error while reading postback information";
                }
            }
        }
        /// <summary> Constructor for a new instance of the Thematic_Headings_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request </param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the home page are organized </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling an edit or new thematic heading is handled here in the constructor </remarks>
        public Thematic_Headings_AdminViewer(User_Object User,
            SobekCM_Navigation_Object Current_Mode,
            List<Thematic_Heading> Thematic_Headings,
			Aggregation_Code_Manager Code_Manager,
            Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Thematic_Headings_AdminViewer.Constructor", String.Empty);

            // Get the current list of thematic headings
            thematicHeadings = Thematic_Headings;

            // Save the mode
            currentMode = Current_Mode;

            // Set action message to nothing to start
            actionMessage = String.Empty;

            // If the user cannot edit this, go back
            if ((!user.Is_System_Admin) && ( !user.Is_Portal_Admin ))
            {
                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Handle any post backs
            if (currentMode.isPostBack)
            {
                try
                {
                    // Pull the standard values from the form
                    NameValueCollection form = HttpContext.Current.Request.Form;
                    string save_value = form["admin_heading_tosave"];
                    string action_value = form["admin_heading_action"];

                    // Switch, depending on the request
                    if (action_value != null)
                    {
                        switch (action_value.Trim().ToLower())
                        {
                            case "edit":
                                string new_name = form["form_heading_name"];
                                if (new_name != null)
                                {
                                    int id = Convert.ToInt32(save_value);
                                    int order = 1 + Thematic_Headings.TakeWhile(ThisHeading => ThisHeading.ThematicHeadingID != id).Count();
                                    if (SobekCM_Database.Edit_Thematic_Heading(id, order, new_name, Tracer) < 1)
                                    {
                                        actionMessage = "Unable to edit existing thematic heading";
                                    }
                                    else
                                    {
                                        // For thread safety, lock the thematic headings list
                                        lock (Thematic_Headings)
                                        {
                                            // Repopulate the thematic headings list
                                            SobekCM_Database.Populate_Thematic_Headings(Thematic_Headings, Tracer);
                                        }

                                        actionMessage = "Thematic heading edits saved";
                                    }
                                }
                                break;

                            case "delete":
                                int thematicDeleteId = Convert.ToInt32(save_value);
                                if (!SobekCM_Database.Delete_Thematic_Heading(thematicDeleteId, Tracer))
                                {
                                    // Set action message
                                    actionMessage = "Unable to delete existing thematic heading";
                                }
                                else
                                {
                                    // For thread safety, lock the thematic headings list
                                    lock (Thematic_Headings)
                                    {
                                        // Remove this thematic heading from the list
                                        int i = 0;
                                        while (i < Thematic_Headings.Count)
                                        {
                                            if (Thematic_Headings[i].ThematicHeadingID == thematicDeleteId)
                                                Thematic_Headings.RemoveAt(i);
                                            else
                                                i++;
                                        }
                                    }

                                    // Set action message
                                    actionMessage = "Thematic heading deleted";
                                }
                                break;

                            case "new":
                                int new_order = Thematic_Headings.Count + 1;
                                int newid = SobekCM_Database.Edit_Thematic_Heading(-1, new_order, save_value, Tracer);
                                if ( newid  < 1)
                                    actionMessage = "Unable to save new thematic heading";
                                else
                                {
                                    // For thread safety, lock the thematic headings list
                                    lock (Thematic_Headings)
                                    {
                                        // Repopulate the thematic headings list
                                        SobekCM_Database.Populate_Thematic_Headings(Thematic_Headings, Tracer);
                                    }

                                    // Add this blank thematic heading to the code manager
                                    Code_Manager.Add_Blank_Thematic_Heading(newid);

                                    actionMessage = "New thematic heading saved";
                                }
                                break;

                            case "moveup":
                                string[] moveup_split = save_value.Split(",".ToCharArray());
                                int moveup_id = Convert.ToInt32(moveup_split[0]);
                                int moveup_order = Convert.ToInt32(moveup_split[1]);
                                if (moveup_order > 1)
                                {
                                    Thematic_Heading themeHeading = Thematic_Headings[moveup_order - 1];
                                    if (themeHeading.ThematicHeadingID == moveup_id)
                                    {
                                        // For thread safety, lock the thematic headings list
                                        lock (Thematic_Headings)
                                        {
                                            // Move this thematic heading up
                                            Thematic_Headings.Remove(themeHeading);
                                            Thematic_Headings.Insert(moveup_order - 2, themeHeading);
                                            int current_order = 1;
                                            foreach (Thematic_Heading thisTheme in Thematic_Headings)
                                            {
                                                SobekCM_Database.Edit_Thematic_Heading(thisTheme.ThematicHeadingID, current_order, thisTheme.ThemeName, Tracer);
                                                current_order++;
                                            }

                                            // Repopulate the thematic headings list
                                            SobekCM_Database.Populate_Thematic_Headings(Thematic_Headings, Tracer);
                                        }
                                    }
                                }
                                break;

                            case "movedown":
                                string[] movedown_split = save_value.Split(",".ToCharArray());
                                int movedown_id = Convert.ToInt32(movedown_split[0]);
                                int movedown_order = Convert.ToInt32(movedown_split[1]);
                                if (movedown_order < Thematic_Headings.Count)
                                {
                                    Thematic_Heading themeHeading = Thematic_Headings[movedown_order - 1];
                                    if (themeHeading.ThematicHeadingID == movedown_id)
                                    {
                                        // For thread safety, lock the thematic headings list
                                        lock (Thematic_Headings)
                                        {
                                            // Move this thematic heading down
                                            Thematic_Headings.Remove(themeHeading);
                                            Thematic_Headings.Insert(movedown_order, themeHeading);
                                            int current_order = 1;
                                            foreach (Thematic_Heading thisTheme in Thematic_Headings)
                                            {
                                                SobekCM_Database.Edit_Thematic_Heading(thisTheme.ThematicHeadingID, current_order, thisTheme.ThemeName, Tracer);
                                                current_order++;
                                            }

                                            // Repopulate the thematic headings list
                                            SobekCM_Database.Populate_Thematic_Headings(Thematic_Headings, Tracer);
                                        }
                                    }
                                }
                                break;

                        }
                    }
                }
                catch (Exception)
                {
                    actionMessage = "Unknown error caught while handling your reqeust";
                }
            }
        }
        /// <summary> Constructor for a new instance of the Wordmarks_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from editing an existing wordmark, deleting a wordmark, or creating a new wordmark is handled here in the constructor </remarks>
        public Wordmarks_AdminViewer(User_Object User, SobekCM_Navigation_Object Current_Mode, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Wordmarks_AdminViewer.Constructor", String.Empty);

            // Save the mode and settings  here
            currentMode = Current_Mode;

            // Set action message to nothing to start
            actionMessage = String.Empty;

            // If the user cannot edit this, go back
            if ((user == null ) || ((!user.Is_System_Admin) && ( !user.Is_Portal_Admin )))
            {
                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Get the wordmark directory and ensure it exists
            wordmarkDirectory = HttpContext.Current.Server.MapPath("design/wordmarks");
            if (!Directory.Exists(wordmarkDirectory))
                Directory.CreateDirectory(wordmarkDirectory);

            // Get the list of all wordmarks
            wordmarks = new Dictionary<string, Wordmark_Icon>();
            SobekCM_Database.Populate_Icon_List(wordmarks, Tracer);

            // If this is a postback, handle any events first
               // if (currentMode.isPostBack)
               // {
                try
                {
                    // Pull the standard values
                    NameValueCollection form = HttpContext.Current.Request.Form;
                    if (form["admin_wordmark_code_delete"] != null)
                    {
                        string delete_value = form["admin_wordmark_code_delete"].ToUpper().Trim();
                        string save_value = form["admin_wordmark_code_tosave"].ToUpper().Trim();
                        string new_wordmark_code = form["admin_wordmark_code"].ToUpper().Trim();

                        // Was this a reset request?
                        if (delete_value.Length > 0)
                        {
                            // If the value to delete does not have a period, then it has no extension,
                            // so this is to delete a USED wordmark which is both a file AND in the database
                            if (delete_value.IndexOf(".") < 0)
                            {
                                Tracer.Add_Trace("Wordmarks_AdminViewer.Constructor", "Delete wordmark '" + delete_value + "' from the database");

                                // Get the wordmark, so we can also delete the file
                                Wordmark_Icon deleteIcon = wordmarks[delete_value];

                                // Delete from the database
                                if (SobekCM_Database.Delete_Icon(delete_value, Tracer))
                                {
                                    // Set the deleted wordmark message
                                    actionMessage = "Deleted wordmark <i>" + delete_value + "</i>";

                                    // Try to delete the file related to this wordmark now
                                    if ((deleteIcon != null) && (File.Exists(wordmarkDirectory + "\\" + deleteIcon.Image_FileName)))
                                    {
                                        try
                                        {
                                            File.Delete(wordmarkDirectory + "\\" + deleteIcon.Image_FileName);
                                        }
                                        catch (Exception)
                                        {
                                            actionMessage = "Deleted wordmark <i>" + delete_value + "</i> but unable to delete the file <i>" + deleteIcon.Image_FileName + "</i>";
                                        }
                                    }

                                    // Repull the wordmark list now
                                    wordmarks = new Dictionary<string, Wordmark_Icon>();
                                    SobekCM_Database.Populate_Icon_List(wordmarks, Tracer);
                                }
                                else
                                {
                                    // Report the error
                                    if (SobekCM_Database.Last_Exception == null)
                                    {
                                        actionMessage = "Unable to delete wordmark <i>" + delete_value + "</i> since it is in use";
                                    }
                                    else
                                    {
                                        actionMessage = "Unknown error while deleting wordmark <i>" + delete_value + "</i>";
                                    }
                                }
                            }
                            else
                            {
                                // This is to delete just a file, which presumably is unused by the system
                                // and does not appear in the database
                                // Try to delete the file related to this wordmark now
                                if (File.Exists(wordmarkDirectory + "\\" + delete_value))
                                {
                                    try
                                    {
                                        File.Delete(wordmarkDirectory + "\\" + delete_value);
                                        actionMessage = "Deleted unused image file <i>" + delete_value + "</i>";
                                    }
                                    catch (Exception)
                                    {
                                        actionMessage = "Unable to delete unused image <i>" + delete_value + "</i>";
                                    }
                                }
                            }
                        }
                        else
                        {
                            // Or.. was this a save request
                            if (save_value.Length > 0)
                            {
                                Tracer.Add_Trace("Wordmarks_AdminViewer.Constructor", "Save wordmark '" + save_value + "'");

                                // Was this to save a new interface (from the main page) or edit an existing (from the popup form)?
                                if (save_value == new_wordmark_code)
                                {
                                    string new_file = form["admin_wordmark_file"].Trim();
                                    string new_link = form["admin_wordmark_link"].Trim();
                                    string new_title = form["admin_wordmark_title"].Trim();

                                    // Save this new wordmark
                                    if (SobekCM_Database.Save_Icon(new_wordmark_code, new_file, new_link, new_title, Tracer) > 0)
                                    {
                                        actionMessage = "Saved new wordmark <i>" + save_value + "</i>";
                                    }
                                    else
                                    {
                                        actionMessage = "Unable to save new wordmark <i>" + save_value + "</i>";
                                    }
                                }
                                else
                                {
                                    string edit_file = form["form_wordmark_file"].Trim();
                                    string edit_link = form["form_wordmark_link"].Trim();
                                    string edit_title = form["form_wordmark_title"].Trim();

                                    // Save this existing wordmark
                                    if (SobekCM_Database.Save_Icon(save_value, edit_file, edit_link, edit_title, Tracer) > 0)
                                    {
                                        actionMessage = "Edited existing wordmark <i>" + save_value + "</i>";
                                    }
                                    else
                                    {
                                        actionMessage = "Unable to edit existing wordmark <i>" + save_value + "</i>";
                                    }
                                }

                                // Repull the wordmark list now
                                wordmarks = new Dictionary<string, Wordmark_Icon>();
                                SobekCM_Database.Populate_Icon_List(wordmarks, Tracer);
                            }
                        }
                    }
                }
                catch ( Exception )
                {
                    actionMessage = "Unknown error caught while handing request.";
                }
            //}

            // Get the list of wordmarks in the directory
            string[] allFiles = SobekCM_File_Utilities.GetFiles(wordmarkDirectory, "*.jpg|*.jpeg|*.png|*.gif|*.bmp");
            loweredFiles = allFiles.Select(ThisFileName => new FileInfo(ThisFileName)).Select(ThisFileInfo => ThisFileInfo.Name.ToLower()).ToList();
            loweredFiles.Sort();

            // Get the list of all assigned wordmark files
            foreach (Wordmark_Icon thisWordmark in wordmarks.Values)
            {
                if (loweredFiles.Contains(thisWordmark.Image_FileName.ToLower()))
                    loweredFiles.Remove(thisWordmark.Image_FileName.ToLower());
            }
        }
        /// <summary> Performs a search ( or retrieves the search results from the cache ) and outputs the results and search url used  </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="All_Items_Lookup"> Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Aggregation_Object"> Object for the current aggregation object, against which this search is performed </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <param name="Complete_Result_Set_Info"> [OUT] Information about the entire set of results </param>
        /// <param name="Paged_Results"> [OUT] List of search results for the requested page of results </param>
        public void Get_Search_Results(SobekCM_Navigation_Object Current_Mode,
                                       Item_Lookup_Object All_Items_Lookup,
                                       Item_Aggregation Aggregation_Object,
                                       Custom_Tracer Tracer,
                                       out Search_Results_Statistics Complete_Result_Set_Info,
                                       out List<iSearch_Title_Result> Paged_Results )
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("SobekCM_Assistant.Get_Search_Results", String.Empty);
            }

            // Set output initially to null
            Paged_Results = null;
            Complete_Result_Set_Info = null;

            // Get the sort
            int sort = Current_Mode.Sort;
            if ((sort != 0) && (sort != 1) && (sort != 2) && (sort != 10) && (sort != 11))
                sort = 0;

            // Depending on type of search, either go to database or Greenstone
            if (Current_Mode.Search_Type == Search_Type_Enum.Map)
            {
                try
                {
                    double lat1 = 1000;
                    double long1 = 1000;
                    double lat2 = 1000;
                    double long2 = 1000;
                    string[] terms = Current_Mode.Coordinates.Split(",".ToCharArray());
                    if (terms.Length < 2)
                    {
                        Current_Mode.Mode = Display_Mode_Enum.Search;
                        Current_Mode.Redirect();
                        return;
                    }
                    if (terms.Length < 4)
                    {
                        lat1 = Convert.ToDouble(terms[0]);
                        lat2 = lat1;
                        long1 = Convert.ToDouble(terms[1]);
                        long2 = long1;
                    }
                    if (terms.Length >= 4)
                    {
                        if (terms[0].Length > 0)
                            lat1 = Convert.ToDouble(terms[0]);
                        if (terms[1].Length > 0)
                            long1 = Convert.ToDouble(terms[1]);
                        if (terms[2].Length > 0)
                            lat2 = Convert.ToDouble(terms[2]);
                        if (terms[3].Length > 0)
                            long2 = Convert.ToDouble(terms[3]);
                    }

                    // If neither point is valid, return
                    if (((lat1 == 1000) || (long1 == 1000)) && ((lat2 == 1000) || (long2 == 1000)))
                    {
                        Current_Mode.Mode = Display_Mode_Enum.Search;
                        Current_Mode.Redirect();
                        return;
                    }

                    // If just the first point is valid, use that
                    if ((lat2 == 1000) || (long2 == 1000))
                    {
                        lat2 = lat1;
                        long2 = long1;
                    }

                    // If just the second point is valid, use that
                    if ((lat1 == 1000) || (long1 == 1000))
                    {
                        lat1 = lat2;
                        long1 = long2;
                    }

                    // Perform the search against the database
                    try
                    {
                        // Try to pull more than one page, so we can cache the next page or so

                        Multiple_Paged_Results_Args returnArgs = SobekCM_Database.Get_Items_By_Coordinates(Current_Mode.Aggregation, lat1, long1, lat2, long2, false, 20, Current_Mode.Page, sort, false, new List<short>(), true, Tracer);
                        List<List<iSearch_Title_Result>> pagesOfResults = returnArgs.Paged_Results;
                        Complete_Result_Set_Info = returnArgs.Statistics;

                        if ((pagesOfResults != null) && (pagesOfResults.Count > 0))
                            Paged_Results = pagesOfResults[0];
                    }
                    catch (Exception ee)
                    {
                        // Next, show the message to the user
                        Current_Mode.Mode = Display_Mode_Enum.Error;
                        string error_message = ee.Message;
                        if (error_message.ToUpper().IndexOf("TIMEOUT") >= 0)
                        {
                            error_message = "Database Timeout Occurred<br /><br />Try again in a few minutes.<br /><br />";
                        }
                        Current_Mode.Error_Message = error_message;
                        Current_Mode.Caught_Exception = ee;
                    }
                }
                catch
                {
                    Current_Mode.Mode = Display_Mode_Enum.Search;
                    Current_Mode.Redirect();
                }
            }
            else
            {
                List<string> terms = new List<string>();
                List<string> web_fields = new List<string>();

                // Split the terms correctly ( only use the database stop words for the split if this will go to the database ultimately)
                if ((Current_Mode.Search_Type == Search_Type_Enum.Full_Text) || (Current_Mode.Search_Fields.IndexOf("TX") >= 0))
                {
                    Split_Clean_Search_Terms_Fields(Current_Mode.Search_String, Current_Mode.Search_Fields, Current_Mode.Search_Type, terms, web_fields, null, Current_Mode.Search_Precision, ',');
                }
                else
                {
                    Split_Clean_Search_Terms_Fields(Current_Mode.Search_String, Current_Mode.Search_Fields, Current_Mode.Search_Type, terms, web_fields, SobekCM_Library_Settings.Search_Stop_Words, Current_Mode.Search_Precision, ',');
                }

                // Get the count that will be used
                int actualCount = Math.Min(terms.Count, web_fields.Count);

                // Determine if this is a special search type which returns more rows and is not cached.
                // This is used to return the results as XML and DATASET
                bool special_search_type = false;
                int results_per_page = 20;
                if ((Current_Mode.Writer_Type == Writer_Type_Enum.XML) || (Current_Mode.Writer_Type == Writer_Type_Enum.DataSet))
                {
                    results_per_page = 1000000;
                    special_search_type = true;
                    sort = 2; // Sort by BibID always for these
                }

                // Determine if a date range was provided
                long date1 = -1;
                long date2 = -1;
                if (Current_Mode.DateRange_Date1 >= 0)
                {
                    date1 = Current_Mode.DateRange_Date1;
                    if (Current_Mode.DateRange_Date2 >= 0)
                    {
                        if (Current_Mode.DateRange_Date2 >= Current_Mode.DateRange_Date1)
                            date2 = Current_Mode.DateRange_Date2;
                        else
                        {
                            date1 = Current_Mode.DateRange_Date2;
                            date2 = Current_Mode.DateRange_Date1;
                        }
                    }
                    else
                    {
                        date2 = date1;
                    }
                }
                if (date1 < 0)
                {
                    if (Current_Mode.DateRange_Year1 >= 0)
                    {
                        DateTime startDate = new DateTime(Current_Mode.DateRange_Year1, 1, 1);
                        TimeSpan timeElapsed = startDate.Subtract(new DateTime(1, 1, 1));
                        date1 = (long)timeElapsed.TotalDays;
                        if (Current_Mode.DateRange_Year2 >= 0)
                        {
                            startDate = new DateTime(Current_Mode.DateRange_Year2, 12, 31);
                            timeElapsed = startDate.Subtract(new DateTime(1, 1, 1));
                            date2 = (long)timeElapsed.TotalDays;
                        }
                        else
                        {
                            startDate = new DateTime(Current_Mode.DateRange_Year1, 12, 31);
                            timeElapsed = startDate.Subtract(new DateTime(1, 1, 1));
                            date2 = (long) timeElapsed.TotalDays;
                        }
                    }
                }

                // Set the flags for how much data is needed.  (i.e., do we need to pull ANYTHING?  or
                // perhaps just the next page of results ( as opposed to pulling facets again).
                bool need_search_statistics = true;
                bool need_paged_results = true;
                if (!special_search_type)
                {
                    // Look to see if the search statistics are available on any cache..
                    Complete_Result_Set_Info = Cached_Data_Manager.Retrieve_Search_Result_Statistics(Current_Mode, actualCount, web_fields, terms, date1, date2, Tracer);
                    if (Complete_Result_Set_Info != null)
                        need_search_statistics = false;

                    // Look to see if the paged results are available on any cache..
                    Paged_Results = Cached_Data_Manager.Retrieve_Search_Results(Current_Mode, sort, actualCount, web_fields, terms, date1, date2, Tracer);
                    if (Paged_Results != null)
                        need_paged_results = false;
                }

                // If both were retrieved, do nothing else
                if ((need_paged_results) || (need_search_statistics))
                {
                    // Should this pull the search from the database, or from greenstone?
                    if ((Current_Mode.Search_Type == Search_Type_Enum.Full_Text) || (Current_Mode.Search_Fields.IndexOf("TX") >= 0))
                    {
                        try
                        {
                            // Perform the search against greenstone
                            Search_Results_Statistics recomputed_search_statistics;
                            Perform_Solr_Search(Tracer, terms, web_fields, actualCount, Current_Mode.Aggregation, Current_Mode.Page, sort, results_per_page, out recomputed_search_statistics, out Paged_Results);
                            if (need_search_statistics)
                                Complete_Result_Set_Info = recomputed_search_statistics;
                        }
                        catch (Exception ee)
                        {
                            Current_Mode.Mode = Display_Mode_Enum.Error;
                            Current_Mode.Error_Message = "Unable to perform search at this time";
                            Current_Mode.Caught_Exception = ee;
                        }

                        // If this was a special search, don't cache this
                        if (!special_search_type)
                        {
                            // Cache the search statistics, if it was needed
                            if ((need_search_statistics) && (Complete_Result_Set_Info != null))
                            {
                                Cached_Data_Manager.Store_Search_Result_Statistics(Current_Mode, actualCount, web_fields, terms, date1, date2, Complete_Result_Set_Info, Tracer);
                            }

                            // Cache the search results
                            if ((need_paged_results) && (Paged_Results != null))
                            {
                                Cached_Data_Manager.Store_Search_Results(Current_Mode, sort, actualCount, web_fields, terms, date1, date2, Paged_Results, Tracer);
                            }
                        }
                    }
                    else
                    {
                        // Try to pull more than one page, so we can cache the next page or so
                        List<List<iSearch_Title_Result>> pagesOfResults = new List<List<iSearch_Title_Result>>();

                        // Perform the search against the database
                        try
                        {
                            Search_Results_Statistics recomputed_search_statistics;
                            Perform_Database_Search(Tracer, terms, web_fields, date1, date2, actualCount, Current_Mode, sort, Aggregation_Object, All_Items_Lookup, results_per_page, !special_search_type, out recomputed_search_statistics, out pagesOfResults, need_search_statistics);
                            if (need_search_statistics)
                                Complete_Result_Set_Info = recomputed_search_statistics;

                            if ((pagesOfResults != null) && (pagesOfResults.Count > 0))
                                Paged_Results = pagesOfResults[0];
                        }
                        catch (Exception ee)
                        {
                            // Next, show the message to the user
                            Current_Mode.Mode = Display_Mode_Enum.Error;
                            string error_message = ee.Message;
                            if (error_message.ToUpper().IndexOf("TIMEOUT") >= 0)
                            {
                                error_message = "Database Timeout Occurred<br /><br />Try narrowing your search by adding more terms <br />or putting quotes around your search.<br /><br />";
                            }
                            Current_Mode.Error_Message = error_message;
                            Current_Mode.Caught_Exception = ee;
                        }

                        // If this was a special search, don't cache this
                        if (!special_search_type)
                        {
                            // Cache the search statistics, if it was needed
                            if ((need_search_statistics) && (Complete_Result_Set_Info != null))
                            {
                                Cached_Data_Manager.Store_Search_Result_Statistics(Current_Mode, actualCount, web_fields, terms, date1, date2, Complete_Result_Set_Info, Tracer);
                            }

                            // Cache the search results
                            if ((need_paged_results) && (pagesOfResults != null))
                            {
                                Cached_Data_Manager.Store_Search_Results(Current_Mode, sort, actualCount, web_fields, terms, date1, date2, pagesOfResults, Tracer);
                            }
                        }
                    }
                }
            }

            ////create search results json object and place into session state
            //DataTable TEMPsearchResults = new DataTable();
            //TEMPsearchResults.Columns.Add("BibID", typeof(string));
            //TEMPsearchResults.Columns.Add("Spatial_Coordinates", typeof(string));
            //foreach (iSearch_Title_Result searchTitleResult in Paged_Results)
            //{
            //	TEMPsearchResults.Rows.Add(searchTitleResult.BibID, searchTitleResult.Spatial_Coordinates);
            //}
            //HttpContext.Current.Session["TEMPSearchResultsJSON"] = Google_Map_ResultsViewer_Beta.Create_JSON_Search_Results_Object(TEMPsearchResults);
        }
        /// <summary> Constructor for a new instance of the New_Group_And_Item_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Current_Item"> Digital resource selected for file management </param>
        /// <param name="Item_List"> Allows individual items to be retrieved by various methods as <see cref="Single_Item"/> objects.</param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Icon_Table"> Dictionary of all the wordmark/icons which can be tagged to the items </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="HTML_Skin_Collection"> HTML Web skin collection which controls the overall appearance of this digital library </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public File_Management_MySobekViewer(User_Object User,
                                             SobekCM_Navigation_Object Current_Mode,
                                             SobekCM_Item Current_Item,
                                             Item_Lookup_Object Item_List,
                                             Aggregation_Code_Manager Code_Manager,
                                             Dictionary<string, Wordmark_Icon> Icon_Table,
                                             SobekCM_Skin_Object HTML_Skin,
                                             Language_Support_Info Translator,
											 SobekCM_Skin_Collection HTML_Skin_Collection,
                                             Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("File_Management_MySobekViewer.Constructor", String.Empty);

            // Save the parameters
            codeManager = Code_Manager;
            itemList = Item_List;
            iconList = Icon_Table;
            currentMode = Current_Mode;
            webSkin = HTML_Skin;
            base.Translator = Translator;
            item = Current_Item;
            digitalResourceDirectory = Current_Item.Source_Directory;
            skins = HTML_Skin_Collection;

            // If the user cannot edit this item, go back
            if (!user.Can_Edit_This_Item(item))
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // If this is post-back, handle it
            if (currentMode.isPostBack)
            {
                string[] getKeys = HttpContext.Current.Request.Form.AllKeys;
                string file_name_from_keys = String.Empty;
                string label_from_keys = String.Empty;
                foreach (string thisKey in getKeys)
                {
                    if (thisKey.IndexOf("upload_file") == 0)
                    {
                        file_name_from_keys = HttpContext.Current.Request.Form[thisKey];
                    }
                    if (thisKey.IndexOf("upload_label") == 0)
                    {
                        label_from_keys = HttpContext.Current.Request.Form[thisKey];
                    }
                    if ((file_name_from_keys.Length > 0) && (label_from_keys.Length > 0))
                    {
                        HttpContext.Current.Session["file_" + item.Web.ItemID + "_" + file_name_from_keys.Trim()] = label_from_keys.Trim();
                        file_name_from_keys = String.Empty;
                        label_from_keys = String.Empty;
                    }

                    if (thisKey == "url_input")
                    {
                        item.Bib_Info.Location.Other_URL = HttpContext.Current.Request.Form[thisKey];
                    }
                }

                string action = HttpContext.Current.Request.Form["action"];
                if (action == "delete")
                {
                    string filename = HttpContext.Current.Request.Form["phase"];
                    try
                    {
                        if (File.Exists(digitalResourceDirectory + "\\" + filename))
                            File.Delete(digitalResourceDirectory + "\\" + filename);

                        // Forward
                        currentMode.Redirect();
                        return;
                    }
                    catch
                    {
                        // Error was caught during attempted delete
                    }
                }

                if ( action == "next_phase")
                {
                    int phase = Convert.ToInt32(HttpContext.Current.Request.Form["phase"]);
                    switch( phase )
                    {
                        case 2:
                            // Clear all the file keys in the session state
                            List<string> keys = HttpContext.Current.Session.Keys.Cast<string>().Where(ThisKey => ThisKey.IndexOf("file_" + item.Web.ItemID + "_") == 0).ToList();
                            foreach (string thisKey in keys)
                            {
                                HttpContext.Current.Session.Remove(thisKey);
                            }

                            // Redirect to the item
                            currentMode.Mode = Display_Mode_Enum.Item_Display;
                            currentMode.Redirect();
                            break;

                        case 9:
                            if (!complete_item_submission(item, null))
                            {
                                // Clear all the file keys in the session state
                                List<string> keys2 = HttpContext.Current.Session.Keys.Cast<string>().Where(ThisKey => ThisKey.IndexOf("file_" + item.Web.ItemID + "_") == 0).ToList();
                                foreach (string thisKey in keys2)
                                {
                                    HttpContext.Current.Session.Remove(thisKey);
                                }

                                // Also clear the item from the cache
                                MemoryMgmt.Cached_Data_Manager.Remove_Digital_Resource_Object(item.BibID, item.VID, null);

                                // Redirect to the item
                                currentMode.Mode = Display_Mode_Enum.Item_Display;
                                currentMode.Redirect();
                            }
                            break;
                    }
                }
            }
        }
        /// <summary> Constructor for a new instance of the Edit_Item_Behaviors_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Current_Item"> Individual digital resource to be edited by the user </param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Edit_Item_Behaviors_MySobekViewer(User_Object User, SobekCM_Navigation_Object Current_Mode, SobekCM_Item Current_Item, Aggregation_Code_Manager Code_Manager, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Edit_Item_Behaviors_MySobekViewer.Constructor", String.Empty);

            currentMode = Current_Mode;
            item = Current_Item;

            // If the user cannot edit this item, go back
            if (!user.Can_Edit_This_Item(item))
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            const string TEMPLATE_CODE = "itembehaviors";
            template = Cached_Data_Manager.Retrieve_Template(TEMPLATE_CODE, Tracer);
            if (template != null)
            {
                Tracer.Add_Trace("Edit_Item_Behaviors_MySobekViewer.Constructor", "Found template in cache");
            }
            else
            {
                Tracer.Add_Trace("Edit_Item_Behaviors_MySobekViewer.Constructor", "Reading template file");

                // Read this template
                Template_XML_Reader reader = new Template_XML_Reader();
                template = new Template();
                reader.Read_XML(SobekCM_Library_Settings.Base_MySobek_Directory + "templates\\defaults\\" + TEMPLATE_CODE + ".xml", template, true);

                // Add the current codes to this template
                template.Add_Codes(Code_Manager);

                // Save this into the cache
                Cached_Data_Manager.Store_Template(TEMPLATE_CODE, template, Tracer);
            }

            // See if there was a hidden request
            string hidden_request = HttpContext.Current.Request.Form["behaviors_request"] ?? String.Empty;

            // If this was a cancel request do that
            if (hidden_request == "cancel")
            {
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.Redirect();
            }
            else if (hidden_request == "save")
            {
                // Changes to the tracking box require the metadata search citation be rebuilt for this item
                // so save the old tracking box information first
                string oldTrackingBox = item.Tracking.Tracking_Box;

                // Save these changes to bib
                template.Save_To_Bib(item, user, 1);

                // Save the behaviors
                SobekCM_Database.Save_Behaviors(item, item.Behaviors.Text_Searchable, false );

                // Save the serial hierarchy as well (sort of a behavior)
                SobekCM_Database.Save_Serial_Hierarchy_Information(item, item.Web.GroupID, item.Web.ItemID);

                // Did the tracking box change?
                if (item.Tracking.Tracking_Box != oldTrackingBox)
                {
                    SobekCM_Database.Create_Full_Citation_Value(item.Web.ItemID);
                }

                // Remoe from the caches (to replace the other)
                Cached_Data_Manager.Remove_Digital_Resource_Object(item.BibID, item.VID, Tracer);

                // Also remove the list of volumes, since this may have changed
                Cached_Data_Manager.Remove_Items_In_Title(item.BibID, Tracer);

                // Forward
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.Redirect();
            }
        }
        /// <summary> Constructor for a new instance of the Aggregation_Single_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the home page are organized </param>
        /// <param name="Web_Skin_Collection">  Contains the collection of all the default skins and the data to create any additional skins on request</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling an edit or new aggregation is handled here in the constructor </remarks>
        public Aggregation_Single_AdminViewer(User_Object User, SobekCM_Navigation_Object Current_Mode, Aggregation_Code_Manager Code_Manager, List<Thematic_Heading> Thematic_Headings, SobekCM_Skin_Collection Web_Skin_Collection, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Aggregation_Single_AdminViewer.Constructor", String.Empty);

            // Save the parameters
            thematicHeadings = Thematic_Headings;
            webSkins = Web_Skin_Collection;
            codeManager = Code_Manager;
            currentMode = Current_Mode;

            // Set some defaults
            actionMessage = String.Empty;

            // Get the code for the aggregation being edited
            string code = currentMode.Aggregation;

            // If the user cannot edit this, go back
            if (!user.Is_Aggregation_Curator(code))
            {
                Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Load the item aggregation, either currenlty from the session (if already editing this aggregation )
            // or by reading all the appropriate XML and reading data from the database
            object possibleEditAggregation = HttpContext.Current.Session["Edit_Aggregation_" + code];
            Item_Aggregation cachedInstance = null;
            if (possibleEditAggregation != null)
                cachedInstance = (Item_Aggregation)possibleEditAggregation;

            itemAggregation = Item_Aggregation_Builder.Get_Item_Aggregation(code, String.Empty, cachedInstance, false, false, Tracer);

            // If unable to retrieve this aggregation, send to home
            if (itemAggregation == null)
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // Get the aggregation directory and ensure it exists
            aggregationDirectory = HttpContext.Current.Server.MapPath("design/aggregations/" + itemAggregation.Code );
            if (!Directory.Exists(aggregationDirectory))
                Directory.CreateDirectory(aggregationDirectory);

            // Determine the page
            page = 1;
            if (currentMode.My_Sobek_SubMode == "b")
                page = 2;
            else if (currentMode.My_Sobek_SubMode == "c")
                page = 3;
            else if (currentMode.My_Sobek_SubMode == "d")
                page = 4;
            else if (currentMode.My_Sobek_SubMode == "e")
                page = 5;
            else if (currentMode.My_Sobek_SubMode == "f")
                page = 6;
            else if (currentMode.My_Sobek_SubMode == "g")
                page = 7;
            else if (currentMode.My_Sobek_SubMode == "h")
                page = 8;
            else if (currentMode.My_Sobek_SubMode == "y")
                page = 9;
            else if (currentMode.My_Sobek_SubMode.IndexOf("g_") == 0)
                page = 10;

            // If this is a postback, handle any events first
            if (currentMode.isPostBack)
            {
                try
                {
                    // Pull the standard values
                    NameValueCollection form = HttpContext.Current.Request.Form;

                    // Get the curret action
                    string action = form["admin_aggr_save"];

                    // If no action, then we should return to the current tab page
                    if (action.Length == 0)
                        action = currentMode.My_Sobek_SubMode;

                    // If this is to cancel, handle that here; no need to handle post-back from the
                    // editing form page first
                    if (action == "z")
                    {
                        // Clear the aggregation from the sessions
                        HttpContext.Current.Session["Edit_Aggregation_" + itemAggregation.Code] = null;
                        HttpContext.Current.Session["Item_Aggr_Edit_" + itemAggregation.Code + "_NewLanguages"] = null;

                        // Redirect the user
                        currentMode.Mode = Display_Mode_Enum.Aggregation;
                        currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
                        currentMode.Redirect();
                        return;
                    }

                    // Save the returned values, depending on the page
                    switch (page)
                    {
                        case 1:
                            Save_Page_1_Postback(form);
                            break;

                        case 2:
                            Save_Page_2_Postback(form);
                            break;

                        case 3:
                            Save_Page_3_Postback(form);
                            break;

                        case 4:
                            Save_Page_4_Postback(form);
                            break;

                        case 5:
                            Save_Page_5_Postback(form);
                            break;

                        case 6:
                            Save_Page_6_Postback(form);
                            break;

                        case 7:
                            Save_Page_7_Postback(form);
                            break;

                        case 8:
                            Save_Page_8_Postback(form);
                            break;

                        case 9:
                            Save_Page_CSS_Postback(form);
                            break;

                        case 10:
                            Save_Child_Page_Postback(form);
                            break;
                    }

                    // Should this be saved to the database?
                    if (action == "save")
                    {
                        // Save the new configuration file
                        bool successful_save = (itemAggregation.Write_Configuration_File(SobekCM_Library_Settings.Base_Design_Location + itemAggregation.ObjDirectory));

                        // Save to the database
                        if (!itemAggregation.Save_To_Database(user.Full_Name,null))
                            successful_save = false;

                        // Save the link between this item and the thematic heading
                        codeManager.Set_Aggregation_Thematic_Heading(itemAggregation.Code, itemAggregation.Thematic_Heading_ID);

                        // Clear the aggregation from the cache
                        Cached_Data_Manager.Remove_Item_Aggregation(itemAggregation.Code, null);

                        // Forward back to the aggregation home page, if this was successful
                        if (successful_save)
                        {
                            // Clear the aggregation from the sessions
                            HttpContext.Current.Session["Edit_Aggregation_" + itemAggregation.Code] = null;
                            HttpContext.Current.Session["Item_Aggr_Edit_" + itemAggregation.Code + "_NewLanguages"] = null;

                            // Redirect the user
                            currentMode.Mode = Display_Mode_Enum.Aggregation;
                            currentMode.Aggregation_Type = Aggregation_Type_Enum.Home;
                            currentMode.Redirect();
                        }
                        else
                        {
                            actionMessage = "Error saving aggregation information!";
                        }
                    }
                    else
                    {
                        // In some cases, skip this part
                        if (((page == 8) && (action == "h")) || ((page == 7) && (action == "g")))
                            return;

                        // Save to the admins session
                        HttpContext.Current.Session["Edit_Aggregation_" + itemAggregation.Code] = itemAggregation;
                        currentMode.My_Sobek_SubMode = action;
                        HttpContext.Current.Response.Redirect(currentMode.Redirect_URL(), false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        currentMode.Request_Completed = true;
                    }
                }
                catch
                {
                    actionMessage = "Unable to correctly parse postback data.";
                }
            }
        }
        /// <summary> Constructor for a new instance of the Aliases_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="CurrentMode"> Mode / navigation information for the current request</param>
        /// <param name="Aggregation_Aliases"> Dictionary of all current item aggregation aliases </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling an edit or new item aggregation alias is handled here in the constructor </remarks>
        public Aliases_AdminViewer(User_Object User, SobekCM_Navigation_Object CurrentMode, Dictionary<string,string> Aggregation_Aliases, Aggregation_Code_Manager Code_Manager, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Aliases_AdminViewer.Constructor", String.Empty);

            // Save the mode and settings  here
            currentMode = CurrentMode;
            aggregationAliases = Aggregation_Aliases;

            // Set action message to nothing to start
            actionMessage = String.Empty;

            // If the user cannot edit this, go back
            if (( user == null ) || ((!user.Is_System_Admin) && ( !user.Is_Portal_Admin )))
            {
                CurrentMode.Mode = Display_Mode_Enum.My_Sobek;
                CurrentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                CurrentMode.Redirect();
                return;
            }

            // If this is a postback, handle any events first
            if (CurrentMode.isPostBack)
            {
                try
                {
                    // Pull the standard values
                    NameValueCollection form = HttpContext.Current.Request.Form;

                    string save_value = form["admin_forwarding_tosave"].ToLower().Trim();
                    string new_alias = form["admin_forwarding_alias"].ToLower().Trim();

                    // Was this a save request
                    if (save_value.Length > 0)
                    {
                        // If this starts with a '-' this is a delete
                        if (save_value[0] == '-')
                        {
                            if (( user.Is_System_Admin ) && ( save_value.Length > 1 ))
                            {
                                save_value = save_value.Substring(1);
                                Tracer.Add_Trace("Aliases_AdminViewer.Constructor", "Delete alias '" + save_value + "'");
                                if (SobekCM_Database.Delete_Aggregation_Alias(save_value, Tracer))
                                {
                                    if (aggregationAliases.ContainsKey(save_value))
                                        aggregationAliases.Remove( save_value );

                                    actionMessage = "Deleted existing aggregation alias <i>" + save_value + "</i>";
                                }
                            }
                        }
                        else
                        {
                            Tracer.Add_Trace("Aliases_AdminViewer.Constructor", "Save alias '" + save_value + "'");

                            // Was this to save a new alias (from the main page) or edit an existing (from the popup form)?
                            if (save_value == new_alias)
                            {
                                string new_code = form["admin_forwarding_code"].ToLower().Trim();

                                // Validate the code
                                if (new_code.Length > 20)
                                {
                                    actionMessage = "New alias code must be twenty characters long or less";
                                }
                                else if (new_code.Length == 0)
                                {
                                    actionMessage = "You must enter a CODE for this aggregation alias";

                                }
                                else if (Code_Manager[new_code.ToUpper()] != null)
                                {
                                    actionMessage = "Aggregation with this code already exists";
                                }
                                else if (SobekCM_Library_Settings.Reserved_Keywords.Contains(new_code.ToLower()))
                                {
                                    actionMessage = "That code is a system-reserved keyword.  Try a different code.";
                                }

                                // Save this new forwarding
                                if (SobekCM_Database.Save_Aggregation_Alias(save_value, new_code, Tracer))
                                {
                                    if (aggregationAliases.ContainsKey(save_value))
                                        aggregationAliases[save_value] = new_code;
                                    else
                                        aggregationAliases.Add(save_value, new_code);

                                    actionMessage = "Saved new aggregation alias <i>" + save_value + "</i>";
                                }
                                else
                                {
                                    actionMessage = "Unable to save new aggregation alias <i>" + save_value + "</i>";
                                }
                            }
                            else
                            {
                                string edit_code = form["form_forwarding_code"].ToLower().Trim();

                                // Save this existing forwarding
                                if (SobekCM_Database.Save_Aggregation_Alias(save_value, edit_code, Tracer))
                                {
                                    if (aggregationAliases.ContainsKey(save_value))
                                        aggregationAliases[save_value] = edit_code;
                                    else
                                        aggregationAliases.Add(save_value, edit_code);

                                    actionMessage = "Edited existing aggregation alias <i>" + save_value + "</i>";
                                }
                                else
                                {
                                    actionMessage = "Unable to save existing aggregation alias <i>" + save_value + "</i>";
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    actionMessage = "Unknown error caught while processing request";
                }
            }
        }
        /// <summary> Constructor for a new instance of the Preferences_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="CurrentMode"> Mode / navigation information for the current request</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Preferences_MySobekViewer(User_Object User, SobekCM_Navigation_Object CurrentMode, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Preferences_MySobekViewer.Constructor", String.Empty);

            currentMode = CurrentMode;
            validationErrors = new List<string>();

            // Set the text to use for each value (since we use if for the validation errors as well)
            mySobekText = "my" + currentMode.SobekCM_Instance_Abbreviation;

            // Get the labels to use, by language
            accountInfoLabel = "Account Information";
            userNameLabel = "UserName";
            personalInfoLabel = "Personal Information";
            familyNamesLabel = "Last/Family Name(s)";
            givenNamesLabel = "First/Given Name(s)";
            nicknameLabel = "Nickname";
            emailLabel = "Email";
            emailStatsLabel = "Send me monthly usage statistics for my items";
            affilitionInfoLabel = "Current Affiliation Information";
            organizationLabel = "Organization/University";
            collegeLabel = "College";
            departmentLabel = "Department";
            unitLabel = "Unit";
            selfSubmittalPrefLabel = "Self-Submittal Preferences";
            sendEmailLabel = "Send me an email when I submit new items";
            templateLabel = "Template";
            projectLabel = "Default Metadata";
            defaultRightsLabel = "Default Rights";
            rightsExplanationLabel = "(These are the default rights you give for sharing, repurposing, or remixing your item to other users. You can set this with each new item you submit, but this will be the default that appears.)";
            rightsInstructionLabel = "You may also select a <a title=\"Explanation of different creative commons licenses.\" href=\"http://creativecommons.org/about/licenses/\">Creative Commons License</a> option below.";
            otherPreferencesLabel = "Other Preferences";
            languageLabel = "Language";
            passwordLabel = "Password";
            confirmPasswordLabel = "Confirm Password";
            col1Width = "15px";
            col2Width = "100px";
            col3Width = "605px";

            if (currentMode.Language == Web_Language_Enum.French)
            {
                accountInfoLabel = "Informations sur le Compte";
                userNameLabel = "Nom du Compte";
                personalInfoLabel = "Des Renseignements Personnels";
                familyNamesLabel = "Nom de Famille";
                givenNamesLabel = "Prénoms";
                nicknameLabel = "Pseudo";
                emailLabel = "Email";
                affilitionInfoLabel = "Information Affiliation Actuel";
                organizationLabel = "Organisation / Université";
                collegeLabel = "Collège";
                departmentLabel = "Département";
                unitLabel = "Unité";
                selfSubmittalPrefLabel = "Préférences Auto-Soumission";
                sendEmailLabel = "Envoyez-moi un email lorsque je présente les nouveaux éléments";
                templateLabel = "Modèle";
                projectLabel = "Métadonnées par Défaut";
                defaultRightsLabel = "Droits par Défaut";
                rightsExplanationLabel = "(Ce sont les droits par défaut que vous donnez de partager, d'adapter, ou remixer votre article à d'autres utilisateurs. Vous pouvez fixer cette valeur à chaque nouvel élément que vous soumettez, mais ce sera la valeur par défaut qui s'affiche.)";
                rightsInstructionLabel = "Vous pouvez également sélectionner une option <a title=\"Explication des différentes licences Creative Commons.\" href=\"http://creativecommons.org/about/licenses/\">Creative Commons License</a> ci-dessous.";
                otherPreferencesLabel = "Autres Préférences";
                languageLabel = "Langue";
                passwordLabel = "Mot de Passe";
                confirmPasswordLabel = "Confirmer Mot de Passe";
                col1Width = "10px";
                col2Width = "220px";
                col3Width = "490px";
            }

            if (currentMode.Language == Web_Language_Enum.Spanish)
            {
                accountInfoLabel = "Información de la Cuenta";
                userNameLabel = "Nombre de la Cuenta";
                personalInfoLabel = "Información Personal";
                familyNamesLabel = "Familia Nombre";
                givenNamesLabel = "Nombre de Pila";
                nicknameLabel = "Nickname";
                emailLabel = "Correo Electrónico";
                affilitionInfoLabel = "Información de la Afiliación Actual";
                organizationLabel = "Organización/Universidad";
                collegeLabel = "Colegio";
                departmentLabel = "Departamento";
                unitLabel = "Unidad";
                selfSubmittalPrefLabel = "Preferencias de Presentación Auto-";
                sendEmailLabel = "Enviadme un correo electrónico cuando se presento nuevos temas";
                templateLabel = "Plantilla";
                projectLabel = "Metadatos Predeterminado";
                defaultRightsLabel = "Derechos por Defecto";
                rightsExplanationLabel = "(Estos son los derechos por defecto le dan para compartir, reutilización, o remezclando el tema a otros usuarios. Puede establecer esto con cada artículo nuevo que presentar, pero esto será el valor por defecto que aparece.)";
                rightsInstructionLabel = "También puede seleccionar una opción de  <a title=\"Explicación de las diferentes licencias Creative Commons\" href=\"http://creativecommons.org/about/licenses/\">Creative Commons License</a> a continuación.";
                otherPreferencesLabel = "Otras preferencias";
                languageLabel = "Idioma";
                passwordLabel = "Contraseña";
                confirmPasswordLabel = "Confirmar Contraseña";
                col1Width = "10px";
                col2Width = "220px";
                col3Width = "490px";
            }

            // Is this for registration
            registration = (HttpContext.Current.Session["user"] == null);
            if (registration)
            {
                user = new User_Object();
            }

            // Set some default first
            send_usages_emails = true;
            family_name = String.Empty;
            given_name = String.Empty;
            nickname = String.Empty;
            email = String.Empty;
            organization = String.Empty;
            college = String.Empty;
            department = String.Empty;
            unit = String.Empty;
            template = String.Empty;
            project = String.Empty;
            username = String.Empty;
            password = String.Empty;
            password2 = String.Empty;
            ufid = String.Empty;
            language = String.Empty;
            default_rights = String.Empty;

            // Handle post back
            if (currentMode.isPostBack)
            {
                // Loop through and get the dataa
                string[] getKeys = HttpContext.Current.Request.Form.AllKeys;
                foreach (string thisKey in getKeys)
                {
                    switch (thisKey)
                    {
                        case "prefUserName":
                            username = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "password_enter":
                            password = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "password_confirm":
                            password2 = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefUfid":
                            ufid = HttpContext.Current.Request.Form[thisKey].Trim().Replace("-", "");
                            break;

                        case "prefFamilyName":
                            family_name = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefGivenName":
                            given_name = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefNickName":
                            nickname = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefEmail":
                            email = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefOrganization":
                            organization = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefCollege":
                            college = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefDepartment":
                            department = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefUnit":
                            unit = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefLanguage":
                            string language_temp = HttpContext.Current.Request.Form[thisKey];
                            if (language_temp == "es")
                                language = "Español";
                            if (language_temp == "fr")
                                language = "Français";
                            break;

                        case "prefTemplate":
                            template = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefProject":
                            project = HttpContext.Current.Request.Form[thisKey];
                            break;

                        case "prefAllowSubmit":
                            string submit_value = HttpContext.Current.Request.Form[thisKey];
                            if (submit_value == "allowsubmit")
                                desire_to_upload = true;
                            break;

                        case "prefSendEmail":
                            string submit_value2 = HttpContext.Current.Request.Form[thisKey];
                            send_email_on_submission = submit_value2 == "sendemail";
                            break;

                        case "prefEmailStats":
                            string submit_value3 = HttpContext.Current.Request.Form[thisKey];
                            send_usages_emails = submit_value3 == "sendemail";
                            break;

                        case "prefRights":
                            default_rights = HttpContext.Current.Request.Form[thisKey];
                            break;

                    }
                }

                if (registration)
                {
                    if (username.Trim().Length == 0)
                        validationErrors.Add("Username is a required field");
                    else if (username.Trim().Length < 8)
                        validationErrors.Add("Username must be at least eight digits");
                    if ((password.Trim().Length == 0) || (password2.Trim().Length == 0))
                        validationErrors.Add("Select and confirm a password");
                    if (password.Trim() != password2.Trim())
                        validationErrors.Add("Passwords do not match");
                    else if (password.Length < 8)
                        validationErrors.Add("Password must be at least eight digits");
                    if (ufid.Trim().Length > 0)
                    {
                        if (ufid.Trim().Length != 8)
                        {
                            validationErrors.Add("UFIDs are always eight digits");
                        }
                        else
                        {
                            int ufid_convert_test;
                            if (!Int32.TryParse(ufid, out ufid_convert_test))
                                validationErrors.Add("UFIDs are always numeric");
                        }
                    }
                }

                // Validate the basic data is okay
                if (family_name.Trim().Length == 0)
                    validationErrors.Add("Family name is a required field");
                if (given_name.Trim().Length == 0)
                    validationErrors.Add("Given name is a required field");
                if ((email.Trim().Length == 0) || (email.IndexOf("@") < 0))
                    validationErrors.Add("A valid email is required");
                if (default_rights.Trim().Length > 1000)
                {
                    validationErrors.Add("Rights statement truncated to 1000 characters.");
                    default_rights = default_rights.Substring(0, 1000);
                }

                if ((registration) && (validationErrors.Count == 0))
                {
                    bool email_exists;
                    bool username_exists;
                    SobekCM_Database.UserName_Exists(username, email, out username_exists, out email_exists, Tracer);
                    if (email_exists)
                    {
                        validationErrors.Add("An account for that email address already exists.");
                    }
                    else if (username_exists)
                    {
                        validationErrors.Add("That username is taken.  Please choose another.");
                    }
                }

                if (validationErrors.Count == 0)
                {
                    user.College = college.Trim();
                    user.Department = department.Trim();
                    user.Email = email.Trim();
                    user.Family_Name = family_name.Trim();
                    user.Given_Name = given_name.Trim();
                    user.Nickname = nickname.Trim();
                    user.Organization = organization.Trim();
                    user.Unit = unit.Trim();
                    user.Set_Default_Template(template.Trim());
                    // See if the project is different, if this is not registration
                    if ((!registration) && (user.Default_Metadata_Sets[0] != project.Trim()))
                    {
                        // Determine the in process directory for this
                        string user_in_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.UserName;
                        if (user.ShibbID.Trim().Length > 0)
                            user_in_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.ShibbID;
                        if (Directory.Exists(user_in_process_directory))
                        {
                            if (File.Exists(user_in_process_directory + "\\TEMP000001_00001.mets"))
                                File.Delete(user_in_process_directory + "\\TEMP000001_00001.mets");
                        }
                    }
                    user.Set_Current_Default_Metadata(project.Trim());
                    user.Preferred_Language = language;
                    user.Default_Rights = default_rights;
                    user.Send_Email_On_Submission = send_email_on_submission;
                    user.Receive_Stats_Emails = send_usages_emails;

                    if (registration)
                    {
                        user.Can_Submit = false;
                        user.Send_Email_On_Submission = true;
                        user.ShibbID = ufid;
                        user.UserName = username;
                        user.UserID = -1;

                        // Save this new user
                        SobekCM_Database.Save_User(user, password, user.Authentication_Type, Tracer);

                        // Retrieve the user from the database
                        user = SobekCM_Database.Get_User(username, password, Tracer);

                        // Special code in case this is the very first user
                        if (user.UserID == 1)
                        {
                            // Add each template and project
                            DataSet projectTemplateSet = SobekCM_Database.Get_All_Template_DefaultMetadatas(Tracer);
                            List<string> templates = (from DataRow thisTemplate in projectTemplateSet.Tables[1].Rows select thisTemplate["TemplateCode"].ToString()).ToList();
                            List<string> projects = (from DataRow thisProject in projectTemplateSet.Tables[0].Rows select thisProject["MetadataCode"].ToString()).ToList();

                            // Save the updates to this admin user
                            SobekCM_Database.Save_User(user, password, User_Authentication_Type_Enum.Sobek, Tracer);
                            SobekCM_Database.Update_SobekCM_User(user.UserID, true, true, true, true, true, true, true, "edit_internal", "editmarc_internal", true, true, true, Tracer);
                            SobekCM_Database.Update_SobekCM_User_DefaultMetadata(user.UserID, new ReadOnlyCollection<string>(projects), Tracer);
                            SobekCM_Database.Update_SobekCM_User_Templates(user.UserID, new ReadOnlyCollection<string>(templates), Tracer);

                            // Retrieve the user information again
                            user = SobekCM_Database.Get_User(username, password, Tracer);
                        }

                        user.Is_Just_Registered = true;
                        HttpContext.Current.Session["user"] = user;

                        // If they want to be able to contribue, send an email
                        if (desire_to_upload)
                        {
                            SobekCM_Database.Send_Database_Email(SobekCM_Library_Settings.System_Email, "Submittal rights requested by " + user.Full_Name, "New user requested ability to submit new items.<br /><br /><blockquote>Name: " + user.Full_Name + "<br />Email: " + user.Email + "<br />Organization: " + user.Organization + "<br />User ID: " + user.UserID + "</blockquote>", true, false, -1, -1);
                        }

                        // Email the user their registation information
                        if (desire_to_upload)
                        {
                            SobekCM_Database.Send_Database_Email(email, "Welcome to " + mySobekText, "<strong>Thank you for registering for " + mySobekText + "</strong><br /><br />You can access this directly through the following link: <a href=\"" + currentMode.Base_URL + "/my\">" + currentMode.Base_URL + "/my</a><br /><br />Full Name: " + user.Full_Name + "<br />User Name: " + user.UserName + "<br /><br />You will receive an email when your request to submit items has been processed.", true, false, -1, -1);
                        }
                        else
                        {
                            SobekCM_Database.Send_Database_Email(email, "Welcome to " + mySobekText, "<strong>Thank you for registering for " + mySobekText + "</strong><br /><br />You can access this directly through the following link: <a href=\"" + currentMode.Base_URL + "/my\">" + currentMode.Base_URL + "/my</a><br /><br />Full Name: " + user.Full_Name + "<br />User Name: " + user.UserName, true, false, -1, -1);
                        }

                        // Now, forward back to the My Sobek home page
                        currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;

                        // If this is the first user to register (who would have been set to admin), send to the
                        // system-wide settings screen
                        if (user.UserID == 1)
                        {
                            currentMode.Mode = Display_Mode_Enum.Administrative;
                            currentMode.Admin_Type = Admin_Type_Enum.Settings;
                        }
                        currentMode.Redirect();
                    }
                    else
                    {
                        HttpContext.Current.Session["user"] = user;
                        SobekCM_Database.Save_User(user, String.Empty, user.Authentication_Type,  Tracer);

                        // Now, forward back to the My Sobek home page
                        currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                        currentMode.Redirect();
                    }
                }
            }
            else
            {
                family_name = user.Family_Name;
                given_name = user.Given_Name;
                nickname = user.Nickname;
                email = user.Email;
                organization = user.Organization;
                college = user.College;
                department = user.Department;
                unit = user.Unit;
                username = user.UserName;
                ufid = user.ShibbID;
                language = user.Preferred_Language;
                send_email_on_submission = user.Send_Email_On_Submission;
                default_rights = user.Default_Rights;

            }
        }
        /// <summary> Constructor for a new instance of the Default_Metadata_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="CurrentMode"> Mode / navigation information for the current request</param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling a new project is handled here in the constructor </remarks>
        public Default_Metadata_AdminViewer(User_Object User, SobekCM_Navigation_Object CurrentMode, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Default_Metadata_AdminViewer.Constructor", String.Empty);

            // Save the mode and settings  here
            currentMode = CurrentMode;

            // Set action message to nothing to start
            actionMessage = String.Empty;

            // If the user cannot edit this, go back
            if ((!user.Is_System_Admin ) && ( !user.Is_Portal_Admin ))
            {
                currentMode.Mode = Display_Mode_Enum.My_Sobek;
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            // If this is a postback, handle any events first
            if (currentMode.isPostBack)
            {
                try
                {
                    // Pull the standard values
                    NameValueCollection form = HttpContext.Current.Request.Form;

                    string save_value = form["admin_project_tosave"].ToUpper().Trim();
                    string delete_value = form["admin_project_delete"].ToUpper().Trim();
                    string code_value = form["admin_project_code"].ToUpper().Trim();

                    // Was this a delete request?
                    if (( user.Is_System_Admin ) && ( delete_value.Length > 0))
                    {
                        Tracer.Add_Trace("Default_Metadata_AdminViewer.Constructor", "Delete default metadata '" + delete_value + "'");

                        // Try to delete in the database
                        if (SobekCM_Database.Delete_Project(delete_value, Tracer))
                        {
                            // Set the message
                            actionMessage = "Deletes default metadata '" + delete_value + "'";

                            // Look for the file to delete as well
                            string pmets_file = SobekCM_Library_Settings.Base_MySobek_Directory + "projects\\" + delete_value + ".pmets";
                            if (File.Exists(pmets_file))
                            {
                                try
                                {
                                    File.Delete(pmets_file);
                                }
                                catch
                                {
                                    actionMessage = "Deleted default metadata '" + delete_value + "' but failed to delete associated pmets file";
                                }
                            }
                        }
                        else
                        {
                            actionMessage = "Error encountered deleting default metadata '" + delete_value + "' from the database";
                        }
                    }
                    else if (save_value.Length > 0) // Or.. was this a save request
                    {
                        Tracer.Add_Trace("Default_Metadata_AdminViewer.Constructor", "Save default metadata '" + save_value + "'");

                        // Was this to save a new project (from the main page) or rename an existing (from the popup form)?
                        if (save_value == code_value)
                        {
                            string new_base_code = form["admin_project_base"].ToUpper().Trim();
                            string new_name = form["admin_project_name"].Trim();

                            // Save this new interface
                            if (SobekCM_Database.Save_Default_Metadata(save_value.ToUpper(), new_name, Tracer))
                            {
                                actionMessage = "Saved new default metadata <i>" + save_value + "</i>";
                            }
                            else
                            {
                                actionMessage = "Unable to save new default metadata <i>" + save_value + "</i>";
                            }

                            // Try to creating the PMETS file if there was a base PMETS code provided
                            try
                            {
                                if (new_base_code.Length > 0)
                                {
                                    string pmets_file = SobekCM_Library_Settings.Base_MySobek_Directory + "projects\\" + code_value + ".pmets";
                                    string base_pmets_file = SobekCM_Library_Settings.Base_MySobek_Directory + "projects\\" + new_base_code + ".pmets";

                                    if (File.Exists(base_pmets_file))
                                        File.Copy(base_pmets_file, pmets_file, true);
                                }
                            }
                            catch ( Exception )
                            {
                                actionMessage = "Error copying new default metadata METS to the project folder";
                            }
                        }
                        else
                        {
                            string edit_name = form["form_project_name"].Trim();

                            // Save this existing interface
                            if (SobekCM_Database.Save_Default_Metadata(save_value.ToUpper(), edit_name, Tracer))
                            {
                                actionMessage = "Renamed existing default metadata <i>" + save_value + "</i>";
                            }
                            else
                            {
                                actionMessage = "Unable to rename existing default metadata <i>" + save_value + "</i>";
                            }
                        }
                    }
                }
                catch (Exception )
                {
                    actionMessage = "Unknown exception occurred while processing your request";
                }
            }
        }
        /// <summary> Constructor for a new instance of the Mass_Update_Items_MySobekViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Current_Item"> Individual digital resource to be edited by the user </param>
        /// <param name="Code_Manager"> Code manager contains the list of all valid aggregation codes </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        public Mass_Update_Items_MySobekViewer(User_Object User, SobekCM_Navigation_Object Current_Mode, SobekCM_Item Current_Item,  Aggregation_Code_Manager Code_Manager, Custom_Tracer Tracer)
            : base(User)
        {
            Tracer.Add_Trace("Mass_Update_Items_MySobekViewer.Constructor", String.Empty);
            currentMode = Current_Mode;

            // Since this is a mass update, just create a new empty item with the GroupID included
            // from the provided item
            SobekCM_Item emptyItem = new SobekCM_Item {BibID = Current_Item.BibID};
            emptyItem.Web.GroupID = Current_Item.Web.GroupID;
            emptyItem.Bib_Info.Source.Code = String.Empty;
            emptyItem.Behaviors.CheckOut_Required_Is_Null = true;
            emptyItem.Behaviors.IP_Restriction_Membership_Is_Null = true;
            emptyItem.Behaviors.Dark_Flag_Is_Null = true;
            item = emptyItem;

            // If the user cannot edit this item, go back
            if (!user.Can_Edit_This_Item(Current_Item))
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                currentMode.Redirect();
                return;
            }

            const string TEMPLATE_CODE = "massupdate";
            template = Cached_Data_Manager.Retrieve_Template(TEMPLATE_CODE, Tracer);
            if (template != null)
            {
                Tracer.Add_Trace("Mass_Update_Items_MySobekViewer.Constructor", "Found template in cache");
            }
            else
            {
                Tracer.Add_Trace("Mass_Update_Items_MySobekViewer.Constructor", "Reading template file");

                // Read this template
                Template_XML_Reader reader = new Template_XML_Reader();
                template = new Template();
                reader.Read_XML(SobekCM_Library_Settings.Base_MySobek_Directory + "templates\\defaults\\" + TEMPLATE_CODE + ".xml", template, true);

                // Add the current codes to this template
                template.Add_Codes(Code_Manager);

                // Save this into the cache
                Cached_Data_Manager.Store_Template(TEMPLATE_CODE, template, Tracer);
            }

            // See if there was a hidden request
            string hidden_request = HttpContext.Current.Request.Form["behaviors_request"] ?? String.Empty;

            // If this was a cancel request do that
            if (hidden_request == "cancel")
            {
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.Redirect();
            }
            else if (hidden_request == "save")
            {
                // Save these changes to bib
                template.Save_To_Bib(item, user, 1);

                // Save the behaviors
                SobekCM_Database.Save_Behaviors(item, false, true );

                // Store on the caches (to replace the other)
                Cached_Data_Manager.Remove_Digital_Resource_Objects(item.BibID, Tracer);

                // Forward
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.Redirect();
            }
        }