/// <summary> Constructor for a new instance of the Add_Collection_AdminViewer class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <remarks> Postback from handling an edit or new aggregation is handled here in the constructor </remarks>
        public Add_Collection_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            RequestSpecificValues.Tracer.Add_Trace("Add_Collection_AdminViewer.Constructor", String.Empty);

            // Set some defaults
            actionMessage = String.Empty;
            string page_code = RequestSpecificValues.Current_Mode.My_Sobek_SubMode;

            // If the user is not logged in, they shouldn't be here
            if ((RequestSpecificValues.Current_User == null) || (!RequestSpecificValues.Current_User.LoggedOn ))
            {
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                return;
            }

            // Was there a parent indicated?
            string parent_locked = String.Empty;
            if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["parent"]))
            {
                parent_locked = HttpContext.Current.Request.QueryString["parent"];

                // Ensure that aggregation exists
                if (UI_ApplicationCache_Gateway.Aggregations[parent_locked.ToUpper()] == null)
                {
                    RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                    RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                    UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                    return;
                }
            }

            // Load the new aggregation, either currenlty from the session (if already into this wizard )
            // or by building the new aggregation arguments
            New_Aggregation_Arguments cachedInstance = HttpContext.Current.Session["Add_Coll_Wizard"] as New_Aggregation_Arguments;
            newAggr = cachedInstance ?? new New_Aggregation_Arguments("ALL");

            // Set the code?
            if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["code"]))
            {
                newAggr.Code = HttpContext.Current.Request.QueryString["code"];
            }

            // Lock the parent?
            if (parent_locked.Length > 0)
            {
                // If not already locked, use ths as the parent
                if ((!newAggr.ParentLocked.HasValue) || ( !newAggr.ParentLocked.Value ))
                {
                    newAggr.ParentLocked = true;
                    newAggr.ParentCode = parent_locked;

                    // Also, determine the initial type based on this
                    // Get the type abbreviation
                    Item_Aggregation_Related_Aggregations parentAggr = UI_ApplicationCache_Gateway.Aggregations[newAggr.ParentCode.ToUpper()];
                    newAggr.Type = "Collection";
                    if (parentAggr.Type.IndexOf("Institution", StringComparison.InvariantCultureIgnoreCase) >= 0)
                    {
                        newAggr.Type = "Institutional Division";
                    }
                    else if (parentAggr.Code.ToLower() == "all")
                    {
                        newAggr.Type = "Collection Group";
                    }
                    else if (parentAggr.Type.ToLower() == "collection")
                    {
                        newAggr.Type = "SubCollection";
                    }
                    else if (parentAggr.Type.ToLower() == "collection")
                    {
                        newAggr.Type = "SubCollection";
                    }
                }
            }

            // Check for permissions (if not sys or portal admin)
            if ((!RequestSpecificValues.Current_User.Is_System_Admin) && (!RequestSpecificValues.Current_User.Is_Portal_Admin))
            {
                // If the parent was locked, this could just be a collection curator/admin
                if ((newAggr.ParentLocked.HasValue) && (!newAggr.ParentLocked.Value))
                {
                    if (!RequestSpecificValues.Current_User.Is_Aggregation_Curator(newAggr.ParentCode))
                    {
                        RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                        RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                        UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                        return;
                    }
                }
                else
                {
                    RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.My_Sobek;
                    RequestSpecificValues.Current_Mode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                    UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                    return;
                }
            }

            // Determine the page
            page = 0;
            if (page_code == "a")
                page = 1;
            if (page_code == "b")
                page = 2;
            else if (page_code == "c")
                page = 3;
            else if (page_code == "d")
                page = 4;
            else if (page_code == "e")
                page = 5;
            else if (page_code == "w")
                page = 0;

            // If this was set to page 0, but the user has chosen not to see that again,
            // move straight onto page 1
            if ((page == 0 ) && ( Convert.ToBoolean(RequestSpecificValues.Current_User.Get_Setting("Add_Collection_AdminViewer:Skip Welcome", "false"))))
            {
                page = 1;
            }

            // Determine the in process directory for this
            if (( !String.IsNullOrEmpty(RequestSpecificValues.Current_User.ShibbID)) && ( RequestSpecificValues.Current_User.ShibbID.Trim().Length > 0 ))
            {
                userInProcessDirectory = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.In_Process_Submission_Location, RequestSpecificValues.Current_User.ShibbID + "\\addcoll");
                userInProcessUrl = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_URL, "mySobek/InProcess", RequestSpecificValues.Current_User.ShibbID, "addcoll").Replace("\\","/");
            }
            else
            {
                userInProcessDirectory = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.In_Process_Submission_Location, RequestSpecificValues.Current_User.UserName.Replace(".", "").Replace("@", "") + "\\addcoll");
                userInProcessUrl = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_URL, "mySobek/InProcess", RequestSpecificValues.Current_User.UserName.Replace(".", "").Replace("@", ""), "addcoll").Replace("\\", "/");
            }

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

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

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

                    // 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 add collection wizard info from the sessions
                        HttpContext.Current.Session["Add_Coll_Wizard"] = null;

                        // Delete all the files
                        if (Directory.Exists(userInProcessDirectory + "\\images\\banners"))
                        {
                            string[] banner_files = SobekCM_File_Utilities.GetFiles(userInProcessDirectory + "\\images\\banners", "*.jpg|*.bmp|*.gif|*.png");
                            foreach (string thisFile in banner_files)
                            {
                                try
                                {
                                    File.Delete(thisFile);
                                }
                                catch
                                {
                                }
                            }
                            string[] button_files = SobekCM_File_Utilities.GetFiles(userInProcessDirectory + "\\images\\buttons", "*.gif");
                            foreach (string thisFile in button_files)
                            {
                                try
                                {
                                    File.Delete(thisFile);
                                }
                                catch
                                {
                                }
                            }
                        }

                        // Redirect the user to the aggregation mgmt screen or parent collection
                        if ((newAggr.ParentLocked.HasValue) && (newAggr.ParentLocked.Value) && (!String.IsNullOrEmpty(newAggr.ParentCode)))
                        {
                            // This was from a parent collection, so go back to that
                            RequestSpecificValues.Current_Mode.Admin_Type = Admin_Type_Enum.Aggregation_Single;
                            RequestSpecificValues.Current_Mode.My_Sobek_SubMode = newAggr.ParentCode + "/h";
                        }
                        else
                        {
                            // Send to the main aggregation admin screen
                            RequestSpecificValues.Current_Mode.Admin_Type = Admin_Type_Enum.Aggregations_Mgmt;

                        }
                        UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                        return;
                    }

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

                        case 2:
                            Save_Page_Visibility_Postback(form);
                            break;

                        case 3:
                            Save_Page_Banner_Postback();
                            break;

                        case 4:
                            Save_Page_Buttons_Postback();
                            break;

                        case 5:
                            Save_Page_Success_Postback();
                            break;

                        case 0:
                            Save_Page_Welcome_Postback(form);
                            break;
                    }

                    // Save the changes to the session
                    HttpContext.Current.Session["Add_Coll_Wizard"] = newAggr;

                    // If there was an error message, than do not go on
                    if (actionMessage.Length > 0)
                    {
                        return;
                    }

                    // If there was a save value continue to pull the rest of the data
                    if (action == "save")
                    {
                        // Some final validation
                        // Convert to the integer id for the parent and begin to do checking
                        List<string> errors = new List<string>();
                        if (String.IsNullOrEmpty(newAggr.ParentCode))
                        {
                            errors.Add("You must select a PARENT for this new aggregation");
                        }

                        // Validate the code
                        if (newAggr.Code.Length > 20)
                        {
                            errors.Add("New aggregation code must be twenty characters long or less");
                        }
                        else if (newAggr.Code.Length == 0)
                        {
                            errors.Add("You must enter a CODE for this item aggregation");
                        }
                        else if (UI_ApplicationCache_Gateway.Aggregations[newAggr.Code.ToUpper()] != null)
                        {
                            errors.Add("New code must be unique... <i>" + newAggr.Code + "</i> already exists");
                        }
                        else if (UI_ApplicationCache_Gateway.Settings.Static.Reserved_Keywords.Contains(newAggr.Code.ToLower()))
                        {
                            errors.Add("That code is a system-reserved keyword.  Try a different code.");
                        }
                        else
                        {
                            bool alphaNumericTest = newAggr.Code.All(C => Char.IsLetterOrDigit(C) || C == '_' || C == '-');
                            if (!alphaNumericTest)
                            {
                                errors.Add("New aggregation code must be only letters and numbers");
                                newAggr.Code = newAggr.Code.Replace("\"", "");
                            }
                        }

                        // Was there a type and name
                        if (newAggr.Type.Length == 0)
                        {
                            errors.Add("You must select a TYPE for this new aggregation");
                        }
                        if (newAggr.Description.Length == 0)
                        {
                            errors.Add("You must enter a DESCRIPTION for this new aggregation");
                        }
                        if (newAggr.Name.Length == 0)
                        {
                            errors.Add("You must enter a NAME for this new aggregation");
                        }
                        else
                        {
                            if (newAggr.ShortName.Length == 0)
                                newAggr.ShortName = newAggr.Name;
                        }

                        // If there were errors copy those over to the action message
                        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;
                            return;
                        }

                        // Try to add this aggregation
                        RestResponseMessage msg = SobekEngineClient.Aggregations.Add_New_Aggregation(newAggr);

                        if (msg.ErrorTypeEnum == ErrorRestTypeEnum.Successful)
                        {
                            // Clear all aggregation information (and thematic heading info) from the cache as well
                            CachedDataManager.Aggregations.Clear();

                            // Delete all the files
                            if (Directory.Exists(userInProcessDirectory + "\\images\\banners"))
                            {
                                string[] banner_files = SobekCM_File_Utilities.GetFiles(userInProcessDirectory + "\\images\\banners", "*.jpg|*.bmp|*.gif|*.png");
                                foreach (string thisFile in banner_files)
                                {
                                    try
                                    {
                                        File.Delete(thisFile);
                                    }
                                    catch
                                    {
                                    }
                                }
                                string[] button_files = SobekCM_File_Utilities.GetFiles(userInProcessDirectory + "\\images\\buttons", "*.gif");
                                foreach (string thisFile in button_files)
                                {
                                    try
                                    {
                                        File.Delete(thisFile);
                                    }
                                    catch
                                    {
                                    }
                                }
                            }

                            // If this included a new thematic heading, repopulate that
                            if ((newAggr.NewThematicHeading.HasValue) && (newAggr.NewThematicHeading.Value))
                            {
                                // For thread safety, lock the thematic headings list
                                lock (UI_ApplicationCache_Gateway.Thematic_Headings)
                                {
                                    // Repopulate the thematic headings list
                                    Engine_Database.Populate_Thematic_Headings(UI_ApplicationCache_Gateway.Thematic_Headings, RequestSpecificValues.Tracer);
                                }
                            }

                            // Redirect the user to the new aggregation or parent collection admin
                            if ((newAggr.ParentLocked.HasValue) && (newAggr.ParentLocked.Value) && (!String.IsNullOrEmpty(newAggr.ParentCode)))
                            {
                                // This was from a parent collection, so go back to that
                                RequestSpecificValues.Current_Mode.Admin_Type = Admin_Type_Enum.Aggregation_Single;
                                RequestSpecificValues.Current_Mode.My_Sobek_SubMode = newAggr.ParentCode + "/h";
                            }
                            else
                            {
                                // Forward to the aggregation
                                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Aggregation;
                                RequestSpecificValues.Current_Mode.Aggregation_Type = Aggregation_Type_Enum.Home;
                                RequestSpecificValues.Current_Mode.Aggregation = newAggr.Code;
                            }

                            // Clear the add collection wizard info from the sessions
                            HttpContext.Current.Session["Add_Coll_Wizard"] = null;

                            UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
                        }
                        else
                        {
                            actionMessage = msg.Message;
                        }
                    }
                    else
                    {
                        RequestSpecificValues.Current_Mode.My_Sobek_SubMode = action;
                        HttpContext.Current.Response.Redirect(UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode), false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        RequestSpecificValues.Current_Mode.Request_Completed = true;
                    }
                }
                catch
                {
                    actionMessage = "General error while reading postback information";
                }
            }
            else
            {
                if (!String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["code"]))
                {
                    newAggr.Code = HttpContext.Current.Request.QueryString["code"];
                }
            }
        }
 /// <summary> Add a new aggregation to the system </summary>
 /// <param name="NewAggregation"> Information for the new aggregation </param>
 /// <returns> Message indicating success or any errors encountered </returns>
 public RestResponseMessage Add_New_Aggregation(New_Aggregation_Arguments NewAggregation)
 {
     return AggregationServices.add_new_aggregation(NewAggregation);
 }
        /// <summary> Constructor for a new instance of the Aggregations_Mgmt_AdminViewer class </summary>
        /// <param name="RequestSpecificValues"> All the necessary, non-global data specific to the current request </param>
        /// <remarks> Postback from handling an edit or new aggregation is handled here in the constructor </remarks>
        public Aggregations_Mgmt_AdminViewer(RequestCache RequestSpecificValues)
            : base(RequestSpecificValues)
        {
            RequestSpecificValues.Tracer.Add_Trace("Aggregations_Mgmt_AdminViewer.Constructor", String.Empty);

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

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

            // If this is a postback, handle any events first
            if (RequestSpecificValues.Current_Mode.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, RequestSpecificValues.Current_User.Is_System_Admin, RequestSpecificValues.Current_User.Full_Name, RequestSpecificValues.Tracer, out delete_error);
                        if (errorCode <= 0)
                        {
                            string delete_folder = UI_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + "aggregations\\" + delete_aggregation_code;
                            if (!SobekCM_File_Utilities.Delete_Folders_Recursively(delete_folder))
                                actionMessage = "Deleted '" + delete_aggregation_code.ToUpper() + "' aggregation<br /><br />Unable to remove aggregation directory<br /><br />Some of the files may be in use";
                            else
                                actionMessage = "Deleted '" + delete_aggregation_code.ToUpper() + "' aggregation";
                        }
                        else
                        {
                            actionMessage = delete_error;
                        }

                        CachedDataManager.Aggregations.Clear();

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

                    // If there is a reset request here, purge the aggregation from the cache
                    if (reset_aggregation_code.Length > 0)
                    {
                        CachedDataManager.Aggregations.Remove_Item_Aggregation(reset_aggregation_code, RequestSpecificValues.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)
                        {
                            addedNewCollection = true;

                            // 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();
                            string new_thematic_heading = form["admin_aggr_heading"].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>();
                            if ( String.IsNullOrEmpty(new_parent))
                            {
                                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 (UI_ApplicationCache_Gateway.Aggregations[new_aggregation_code.ToUpper()] != null)
                            {
                                errors.Add("New code must be unique... <i>" + new_aggregation_code + "</i> already exists");
                            }
                            else if (UI_ApplicationCache_Gateway.Settings.Static.Reserved_Keywords.Contains(new_aggregation_code.ToLower()))
                            {
                                errors.Add("That code is a system-reserved keyword.  Try a different code.");
                            }
                            else
                            {
                                bool alphaNumericTest = new_aggregation_code.All(C => Char.IsLetterOrDigit(C) || C == '_' || C == '-');
                                if (!alphaNumericTest)
                                {
                                    errors.Add("New aggregation code must be only letters and numbers");
                                    new_aggregation_code = new_aggregation_code.Replace("\"", "");
                                }
                            }

                            // 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;
                                enteredThematicHeading = new_thematic_heading;
                            }
                            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)
                                string thematicHeading = null;
                                if (form["admin_aggr_heading"] != null)
                                {
                                    int thematicHeadingId = Convert.ToInt32(form["admin_aggr_heading"]);
                                    foreach (Thematic_Heading thisHeading in UI_ApplicationCache_Gateway.Thematic_Headings)
                                    {
                                        if (thisHeading.ID == thematicHeadingId)
                                        {
                                            thematicHeading = thisHeading.Text;
                                            break;
                                        }
                                    }
                                }

                                // Create the new aggregation argument object
                                New_Aggregation_Arguments args = new New_Aggregation_Arguments
                                {
                                    Active = is_active,
                                    Code = new_aggregation_code,
                                    Description = new_description,
                                    External_Link = enteredLink,
                                    Hidden = is_hidden,
                                    Name = new_name,
                                    ParentCode = new_parent,
                                    ShortName = new_shortname,
                                    Thematic_Heading = thematicHeading,
                                    Type = correct_type,
                                    User = RequestSpecificValues.Current_User.Full_Name
                                };

                                // Try to add this aggregation
                                RestResponseMessage msg = SobekEngineClient.Aggregations.Add_New_Aggregation(args);

                                // We are going to save some of the values here anyway, to assist with bulk adds
                                enteredIsActive = is_active;
                                enteredIsHidden = is_hidden;
                                enteredParent = new_parent;
                                enteredType = new_type;
                                enteredLink = new_link;
                                enteredThematicHeading = new_thematic_heading;

                                if (msg.ErrorTypeEnum == ErrorRestTypeEnum.Successful)
                                {
                                    RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Aggregation;
                                    RequestSpecificValues.Current_Mode.Aggregation = new_aggregation_code;
                                    actionMessage = "New item aggregation (" + new_aggregation_code.ToUpper() + ") saved successfully.<br /><br /><a href=\"" + UrlWriterHelper.Redirect_URL(RequestSpecificValues.Current_Mode, true) + "\" target=\"" + new_aggregation_code + "_AGGR\">Click here to view the new aggregation</a>";
                                    RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Administrative;
                                    RequestSpecificValues.Current_Mode.Admin_Type = Admin_Type_Enum.Aggregations_Mgmt;

                                    // Clear all aggregation information (and thematic heading info) from the cache as well
                                    CachedDataManager.Aggregations.Clear();
                                }
                                else
                                {
                                    actionMessage = msg.Message;
                                    enteredCode = new_aggregation_code;
                                    enteredShortname = new_shortname;
                                    enteredName = new_name;
                                    enteredDescription = new_description;
                                }
                            }
                        }
                    }
                }
                catch
                {
                    actionMessage = "General error while reading postback information";
                }
            }
        }
        /// <summary> Add a new aggregation to the system </summary>
        /// <param name="NewAggregation"> Information for the new aggregation </param>
        /// <returns> Message indicating success or any errors encountered </returns>
        public static RestResponseMessage add_new_aggregation(New_Aggregation_Arguments NewAggregation)
        {
            // Convert to the integer id for the parent and begin to do checking
            List<string> errors = new List<string>();
            int parentid = -1;
            if (NewAggregation.ParentCode.Length > 0)
            {
                Item_Aggregation_Related_Aggregations parentAggr = Engine_ApplicationCache_Gateway.Codes[NewAggregation.ParentCode];
                if (parentAggr != null)
                    parentid = parentAggr.ID;
                else
                    errors.Add("Parent code is not valid");
            }
            else
            {
                errors.Add("You must select a PARENT for this new aggregation");
            }

            // Validate the code

            if (NewAggregation.Code.Length > 20)
            {
                errors.Add("New aggregation code must be twenty characters long or less");
            }
            else if (NewAggregation.Code.Length == 0)
            {
                errors.Add("You must enter a CODE for this item aggregation");
            }
            else if (Engine_ApplicationCache_Gateway.Codes[NewAggregation.Code.ToUpper()] != null)
            {
                errors.Add("New code must be unique... <i>" + NewAggregation.Code + "</i> already exists");
            }
            else if (Engine_ApplicationCache_Gateway.Settings.Reserved_Keywords.Contains(NewAggregation.Code.ToLower()))
            {
                errors.Add("That code is a system-reserved keyword.  Try a different code.");
            }
            else
            {
                bool alphaNumericTest = NewAggregation.Code.All(C => Char.IsLetterOrDigit(C) || C == '_' || C == '-');
                if (!alphaNumericTest)
                {
                    errors.Add("New aggregation code must be only letters and numbers");
                    NewAggregation.Code = NewAggregation.Code.Replace("\"", "");
                }
            }

            // Was there a type and name
            if (NewAggregation.Type.Length == 0)
            {
                errors.Add("You must select a TYPE for this new aggregation");
            }
            if (NewAggregation.Description.Length == 0)
            {
                errors.Add("You must enter a DESCRIPTION for this new aggregation");
            }
            if (NewAggregation.Name.Length == 0)
            {
                errors.Add("You must enter a NAME for this new aggregation");
            }
            else
            {
                if (NewAggregation.ShortName.Length == 0)
                    NewAggregation.ShortName = NewAggregation.Name;
            }

            // Check for the thematic heading
            int thematicHeadingId = -1;
            if ( !String.IsNullOrEmpty(NewAggregation.Thematic_Heading))
            {
                // Look for the matching thematic heading
                foreach (Thematic_Heading thisHeading in Engine_ApplicationCache_Gateway.Thematic_Headings)
                {
                    if (String.Compare(thisHeading.Text, NewAggregation.Thematic_Heading, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        thematicHeadingId = thisHeading.ID;
                        break;
                    }
                }

                // If there was no match, the thematic heading was invalid, unless it was new
                if (thematicHeadingId < 0)
                {
                    if ((!NewAggregation.NewThematicHeading.HasValue) || ( !NewAggregation.NewThematicHeading.Value ))
                    {
                        errors.Add("Invalid thematic heading indicated");
                    }
                    else if (errors.Count == 0)
                    {
                        // Add the thematic heading first
                        if ((thematicHeadingId < 0) && (NewAggregation.NewThematicHeading.HasValue) && (NewAggregation.NewThematicHeading.Value))
                        {
                            thematicHeadingId = Engine_Database.Edit_Thematic_Heading(-1, 10, NewAggregation.Thematic_Heading, null);
                        }
                    }
                }
            }

            if (errors.Count > 0)
            {

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

                return new RestResponseMessage(ErrorRestTypeEnum.InputError, actionMessage.ToString());
            }

            string language = Web_Language_Enum_Converter.Enum_To_Code(Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language);

            // Try to save the new item aggregation
            if (!Engine_Database.Save_Item_Aggregation(NewAggregation.Code, NewAggregation.Name, NewAggregation.ShortName, NewAggregation.Description, thematicHeadingId, NewAggregation.Type, NewAggregation.Active, NewAggregation.Hidden, NewAggregation.External_Link, parentid, NewAggregation.User, language, null))
            {
                return new RestResponseMessage(ErrorRestTypeEnum.Exception, "ERROR saving the new item aggregation to the database");
            }
            // Ensure a folder exists for this, otherwise create one
            try
            {
                string folder = Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + "aggregations\\" + NewAggregation.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 + "/html/custom/home");
                    Directory.CreateDirectory(folder + "/images/buttons");
                    Directory.CreateDirectory(folder + "/images/banners");
                    Directory.CreateDirectory(folder + "/uploads");

                    // Get the parent name
                    string link_to_parent = String.Empty;
                    Item_Aggregation_Related_Aggregations parentAggr = Engine_ApplicationCache_Gateway.Codes.Aggregation_By_ID(parentid);
                    if (parentAggr != null)
                    {
                        if (String.Compare(parentAggr.Code, "all", StringComparison.InvariantCultureIgnoreCase) == 0)
                            link_to_parent = "<br />" + Environment.NewLine + " ← Back to <a href=\"<%BASEURL%>\" alt=\"Return to parent collection\">" + parentAggr.Name + "</a>" + Environment.NewLine;
                        else
                            link_to_parent = "<br />" + Environment.NewLine + " ← Back to <a href=\"<%BASEURL%>" + parentAggr.Code + "\" alt=\"Return to parent collection\">" + parentAggr.Name + "</a>" + Environment.NewLine;
                    }

                    // Create a default home text file
                    StreamWriter writer = new StreamWriter(folder + "/html/home/text.html");
                    writer.WriteLine(link_to_parent + "<br />" + Environment.NewLine + "<h3>About " + NewAggregation.Name + "</h3>" + Environment.NewLine + "<p>" + NewAggregation.Description + "</p>" + Environment.NewLine + "<p>To edit this, log on as the aggregation admin and hover over this text to edit it.</p>" + Environment.NewLine + "<br />");

                    writer.Flush();
                    writer.Close();

                    // Was a button indicated, and does it exist?
                    if ((!String.IsNullOrEmpty(NewAggregation.ButtonFile)) && (File.Exists(NewAggregation.ButtonFile)))
                    {
                        File.Copy(NewAggregation.ButtonFile, folder + "/images/buttons/coll.gif");
                    }
                    else
                    {
                        // Copy the default banner and buttons from images
                        if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.png"))
                            File.Copy(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.png", folder + "/images/buttons/coll.png");
                        if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.gif"))
                            File.Copy(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_button.gif", folder + "/images/buttons/coll.gif");

                    }

                    // Was a banner indicated, and does it exist?
                    string banner_file = String.Empty;
                    if ((!String.IsNullOrEmpty(NewAggregation.BannerFile)) && (File.Exists(NewAggregation.BannerFile)))
                    {
                        banner_file = "images/banners/" + Path.GetFileName(NewAggregation.BannerFile);
                        File.Copy(NewAggregation.BannerFile, folder + "//" + banner_file, true);
                    }
                    else
                    {

                        // Try to create a new custom banner
                        bool custom_banner_created = false;

                        // Create the banner with the name of the collection
                        if (Directory.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network + "\\default\\banner_images"))
                        {
                            try
                            {
                                string[] banners = Directory.GetFiles(Engine_ApplicationCache_Gateway.Settings.Servers.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) (Image.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(NewAggregation.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;
                                        banner_file = "images/banners/coll.jpg";
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                // Suppress this Error...
                            }
                        }

                        if ((!custom_banner_created) && (!File.Exists(folder + "/images/banners/coll.jpg")))
                        {
                            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_banner.jpg"))
                            {
                                banner_file = "images/banners/coll.jpg";
                                File.Copy(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "design/aggregations/default_banner.jpg", folder + "/images/banners/coll.jpg", true);
                            }
                        }
                    }

                    // Now, try to create the item aggregation and write the configuration file
                    Custom_Tracer tracer = new Custom_Tracer();
                    Complete_Item_Aggregation itemAggregation = SobekEngineClient.Aggregations.Get_Complete_Aggregation(NewAggregation.Code, true, tracer);
                    if (banner_file.Length > 0)
                    {
                        itemAggregation.Banner_Dictionary.Clear();
                        itemAggregation.Add_Banner_Image(banner_file, Engine_ApplicationCache_Gateway.Settings.System.Default_UI_Language);
                    }
                    itemAggregation.Write_Configuration_File(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Design_Location + itemAggregation.ObjDirectory);

                    // If an email shoudl be sent, do that now
                    if (String.Compare(Engine_ApplicationCache_Gateway.Settings.Email.Send_On_Added_Aggregation, "always", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        string user = String.Empty;
                        if (!String.IsNullOrEmpty(NewAggregation.User))
                            user = NewAggregation.User;

                        string body = "New aggregation added to this system:\n\n\tCode:\t" + itemAggregation.Code + "\n\tType:\t" + itemAggregation.Type + "\n\tName:\t" + itemAggregation.Name + "\n\tShort:\t" + itemAggregation.ShortName + "\n\tUser:\t" + user + "\n\n" + Engine_ApplicationCache_Gateway.Settings.Servers.Application_Server_URL + "/" + itemAggregation.Code;
                        Email_Helper.SendEmail(Engine_ApplicationCache_Gateway.Settings.Email.System_Email, "New " + itemAggregation.Type + " - " + itemAggregation.ShortName, body, false, Engine_ApplicationCache_Gateway.Settings.System.System_Name);
                    }
                }
            }
            catch
            {
                // Reload the list of all codes, to include this new one and the new hierarchy
                lock (Engine_ApplicationCache_Gateway.Codes)
                {
                    Engine_Database.Populate_Code_Manager(Engine_ApplicationCache_Gateway.Codes, null);
                }

                return new RestResponseMessage(ErrorRestTypeEnum.Exception, "ERROR completing the new aggregation add");
            }

            // Reload the list of all codes, to include this new one and the new hierarchy
            lock (Engine_ApplicationCache_Gateway.Codes)
            {
                Engine_Database.Populate_Code_Manager(Engine_ApplicationCache_Gateway.Codes, null);
            }

            // Clear all aggregation information (and thematic heading info) from the cache as well
            CachedDataManager.Aggregations.Clear();

            return new RestResponseMessage(ErrorRestTypeEnum.Successful, null);
        }