/// <summary> Saves a MarcXML file within the digital resource folder </summary>
        /// <param name="Resource"> Incoming digital resource object </param>
        /// <returns> TRUE if processing can continue, FALSE if a critical error occurred which should stop all processing </returns>
        public override bool DoWork(Incoming_Digital_Resource Resource)
        {
            try
            {
                // Set the image location
                Resource.Metadata.Web.Image_Root = Settings.Servers.Image_URL + Resource.Metadata.Web.File_Root.Replace("\\", "/");
                Resource.Metadata.Web.Set_BibID_VID(Resource.Metadata.BibID, Resource.Metadata.VID);

                // Create the options dictionary used when saving information to the database, or writing MarcXML
                Dictionary<string, object> options = new Dictionary<string, object>();
                if (Engine_ApplicationCache_Gateway.Settings.MarcGeneration != null)
                {
                    options["MarcXML_File_ReaderWriter:MARC Cataloging Source Code"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Cataloging_Source_Code;
                    options["MarcXML_File_ReaderWriter:MARC Location Code"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Location_Code;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Agency"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Agency;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Place"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Place;
                    options["MarcXML_File_ReaderWriter:MARC XSLT File"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.XSLT_File;
                }
                options["MarcXML_File_ReaderWriter:System Name"] = Engine_ApplicationCache_Gateway.Settings.System.System_Name;
                options["MarcXML_File_ReaderWriter:System Abbreviation"] = Engine_ApplicationCache_Gateway.Settings.System.System_Abbreviation;

                // Save the marc xml file
                MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                string errorMessage;
                if (!marcWriter.Write_Metadata(Resource.Metadata.Source_Directory + "\\marc.xml", Resource.Metadata, options, out errorMessage))
                {
                    OnError("Error while saving the MarcXML : " + errorMessage, Resource.BibID + ":" + Resource.VID, Resource.METS_Type_String, Resource.BuilderLogId);
                }

            }
            catch (Exception ee)
            {
                OnError("Exception caught while saving the MarcXML : " + ee.Message, Resource.BibID + ":" + Resource.VID, Resource.METS_Type_String, Resource.BuilderLogId);
            }

            return true;
        }
        private void complete_item_submission(SobekCM_Item Item_To_Complete, Custom_Tracer Tracer)
        {
            // If this is a newspaper type, and the pubdate has a value, try to use that for the serial heirarchy
            if ((Item_To_Complete.Behaviors.Serial_Info.Count == 0) && (Item_To_Complete.Bib_Info.Origin_Info.Date_Issued.Length > 0) && (Item_To_Complete.Bib_Info.SobekCM_Type == TypeOfResource_SobekCM_Enum.Newspaper ))
            {
                    DateTime asDateTime;
                    if (DateTime.TryParse(Item_To_Complete.Bib_Info.Origin_Info.Date_Issued, out asDateTime))
                    {
                        hierarchyCopiedFromDate = true;
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(1, asDateTime.Year, asDateTime.Year.ToString());
                        switch (asDateTime.Month)
                        {
                            case 1:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "January");
                                break;

                            case 2:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "February");
                                break;

                            case 3:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "March");
                                break;

                            case 4:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "April");
                                break;

                            case 5:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "May");
                                break;

                            case 6:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "June");
                                break;

                            case 7:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "July");
                                break;

                            case 8:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "August");
                                break;

                            case 9:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "September");
                                break;

                            case 10:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "October");
                                break;

                            case 11:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "November");
                                break;

                            case 12:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "December");
                                break;
                        }

                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(3, asDateTime.Day, asDateTime.Day.ToString());
                    }
            }

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

            // Ensure this directory exists
            if (!Directory.Exists(user_in_process_directory))
                Directory.CreateDirectory(user_in_process_directory);

            // Now, delete all the files in the processing directory
            string[] all_files = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in all_files)
            {
                File.Delete(thisFile);
            }

            // Save to the database
            Item_To_Complete.Web.File_Root = Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8, 2);
            SobekCM_Database.Save_New_Digital_Resource(Item_To_Complete, false, false, user.UserName, String.Empty, -1);

            // Assign the file root and assoc file path
            Item_To_Complete.Web.AssocFilePath = Item_To_Complete.Web.File_Root + "\\" + Item_To_Complete.VID + "\\";

            // Create the static html pages
            string base_url = currentMode.Base_URL;
            try
            {
                Static_Pages_Builder staticBuilder = new Static_Pages_Builder(SobekCM_Library_Settings.System_Base_URL, SobekCM_Library_Settings.Base_Data_Directory, Translator, codeManager, iconList, skins, webSkin.Skin_Code);
                string filename = user_in_process_directory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html";
                staticBuilder.Create_Item_Citation_HTML(Item_To_Complete, filename, String.Empty);

                // Copy the static HTML file to the web server
                try
                {
                    if (!Directory.Exists(SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8)))
                        Directory.CreateDirectory(SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8));
                    if (File.Exists(user_in_process_directory + "\\" + item.BibID + "_" + item.VID + ".html"))
                        File.Copy(user_in_process_directory + "\\" + item.BibID + "_" + item.VID + ".html", SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8) + "\\" + item.BibID + "_" + item.VID + ".html", true);
                }
                catch (Exception)
                {
                    // This is not critical
                }

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

            currentMode.Base_URL = base_url;

            // Save the rest of the metadata
            Item_To_Complete.Source_Directory = user_in_process_directory;
            Item_To_Complete.Save_SobekCM_METS();

            // Add this to the cache
            itemList.Add_SobekCM_Item(Item_To_Complete);

            Database.SobekCM_Database.Add_Item_To_User_Folder(user.UserID, "Submitted Items", Item_To_Complete.BibID, Item_To_Complete.VID, 0, String.Empty, Tracer);

            // Save Bib_Level METS?
            //SobekCM.Resource_Object.Writers.OAI_Writer oaiWriter = new SobekCM.Resource_Object.Writers.OAI_Writer();
            //oaiWriter.Save_OAI_File(bibPackage, resource_folder + "\\oai_dc.xml", bibPackage.Processing_Parameters.Collection_Primary.ToLower(), createDate);

            // If there was no match, try to save to the tracking database
            Database.SobekCM_Database.Tracking_Online_Submit_Complete(Item_To_Complete.Web.ItemID, user.Full_Name, String.Empty);

            // Save the MARC file
            List<string> collectionnames = new List<string>();
            MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
            string errorMessage;
            Dictionary<string, object> options = new Dictionary<string, object>();
            options["MarcXML_File_ReaderWriter:Additional_Tags"] = Item_To_Complete.MARC_Sobek_Standard_Tags(collectionnames, true, SobekCM_Library_Settings.System_Name, SobekCM_Library_Settings.System_Abbreviation);
            marcWriter.Write_Metadata(Item_To_Complete.Source_Directory + "\\marc.xml", Item_To_Complete, options, out errorMessage);

            // Copy this to all the image servers
            SobekCM_Library_Settings.Refresh(Database.SobekCM_Database.Get_Settings_Complete(Tracer));

            // Copy all the files over to the server
            string serverNetworkFolder = SobekCM_Library_Settings.Image_Server_Network + Item_To_Complete.Web.AssocFilePath;

            // Create the folder
            if (!Directory.Exists(serverNetworkFolder))
                Directory.CreateDirectory(serverNetworkFolder);
            if (!Directory.Exists(serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME))
                Directory.CreateDirectory(serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME);

            // Copy the static HTML page over first
            if (File.Exists(user_in_process_directory + "\\" + item.BibID + "_" + item.VID + ".html"))
            {
                File.Copy(user_in_process_directory + "\\" + item.BibID + "_" + item.VID + ".html", serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME + "\\" + item.BibID + "_" + item.VID + ".html", true);
                File.Delete(user_in_process_directory + "\\" + item.BibID + "_" + item.VID + ".html");
            }

            // Copy all the files
            string[] allFiles = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in allFiles)
            {
                string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                File.Copy(thisFile, destination_file, true);
            }

            // Add this to the cache
            itemList.Add_SobekCM_Item(Item_To_Complete);

            // Incrememnt the count of number of items submitted by this user
            user.Items_Submitted_Count++;

            // Delete any remaining items
            all_files = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in all_files)
            {
                File.Delete(thisFile);
            }
        }
        private bool complete_item_submission(SobekCM_Item Item_To_Complete,  Custom_Tracer Tracer )
        {
            // Set an initial flag
            criticalErrorEncountered = false;
            bool xml_found = false;

            string[] all_files = Directory.GetFiles(userInProcessDirectory);
            SortedList<string, List<string>> image_files = new SortedList<string, List<string>>();
            SortedList<string, List<string>> download_files = new SortedList<string, List<string>>();
            foreach (string thisFile in all_files)
            {
                FileInfo thisFileInfo = new FileInfo(thisFile);

                if ((thisFileInfo.Name.IndexOf("agreement.txt") != 0) && (thisFileInfo.Name.IndexOf("TEMP000001_00001.mets") != 0) && (thisFileInfo.Name.IndexOf("doc.xml") != 0) && (thisFileInfo.Name.IndexOf("ufdc_mets.xml") != 0) && (thisFileInfo.Name.IndexOf("marc.xml") != 0))
                {
                    // Get information about this files name and extension
                    string extension_upper = thisFileInfo.Extension.ToUpper();
                    string filename_sans_extension = thisFileInfo.Name.Replace(thisFileInfo.Extension, "");
                    string name_upper = thisFileInfo.Name.ToUpper();

                    // Is this a page image?
                    if ((extension_upper == ".JPG") || (extension_upper == ".TIF") || (extension_upper == ".JP2") || (extension_upper == ".JPX"))
                    {
                        // Exclude .QC.jpg files
                        if (name_upper.IndexOf(".QC.JPG") < 0)
                        {
                            // If this is a thumbnail, trim off the THM part on the file name
                            if (name_upper.IndexOf("THM.JPG") > 0)
                            {
                                filename_sans_extension = filename_sans_extension.Substring(0, filename_sans_extension.Length - 3);
                            }

                            // Is this the first image file with this name?
                            if (image_files.ContainsKey(filename_sans_extension.ToLower()))
                            {
                                image_files[filename_sans_extension.ToLower()].Add(thisFileInfo.Name);
                            }
                            else
                            {
                                List<string> newImageGrouping = new List<string> {thisFileInfo.Name};
                                image_files[filename_sans_extension.ToLower()] = newImageGrouping;
                            }
                        }
                    }
                    else
                    {
                        // If this does not match the exclusion regular expression, than add this
                        if (!Regex.Match(thisFileInfo.Name, UI_ApplicationCache_Gateway.Settings.Resources.Files_To_Exclude_From_Downloads, RegexOptions.IgnoreCase).Success)
                        {
                            // Also, exclude files that are .XML and marc.xml, or doc.xml, or have the bibid in the name
                            if ((thisFileInfo.Name.IndexOf("marc.xml", StringComparison.OrdinalIgnoreCase) != 0) && (thisFileInfo.Name.IndexOf("marc.xml", StringComparison.OrdinalIgnoreCase) != 0) && (thisFileInfo.Name.IndexOf(".mets", StringComparison.OrdinalIgnoreCase) < 0))
                            {
                                // Is this the first image file with this name?
                                if (download_files.ContainsKey(filename_sans_extension.ToLower()))
                                {
                                    download_files[filename_sans_extension.ToLower()].Add(thisFileInfo.Name);
                                }
                                else
                                {
                                    List<string> newDownloadGrouping = new List<string> {thisFileInfo.Name};
                                    download_files[filename_sans_extension.ToLower()] = newDownloadGrouping;
                                }

                                if (thisFileInfo.Name.IndexOf(".xml", StringComparison.OrdinalIgnoreCase) > 0)
                                    xml_found = true;
                            }
                        }
                    }
                }
            }

            // This package is good to go, so build it, save, etc...
            try
            {
                // Save the METS file to the database and back to the directory
                Item_To_Complete.Source_Directory = userInProcessDirectory;

                // Step through and add each file
                Item_To_Complete.Divisions.Download_Tree.Clear();
                if ((completeTemplate.Upload_Types == CompleteTemplate.Template_Upload_Types.File_or_URL) || (completeTemplate.Upload_Types == CompleteTemplate.Template_Upload_Types.File))
                {
                    // Step through each file

                    bool error_reading_file_occurred = false;

                    // Add the image files first
                    bool jpeg_added = false;
                    bool jp2_added = false;
                    foreach(string thisFileKey in image_files.Keys )
                    {
                        // Get the list of files
                        List<string> theseFiles = image_files[thisFileKey];

                        // Add each file
                        foreach (string thisFile in theseFiles)
                        {
                            // Create the new file object and compute a label
                            FileInfo fileInfo = new FileInfo(thisFile);
                            SobekCM_File_Info newFile = new SobekCM_File_Info(fileInfo.Name);
                            string label = fileInfo.Name.Replace(fileInfo.Extension, "");
                            if (HttpContext.Current.Session["file_" + thisFileKey] != null)
                            {
                                string possible_label = HttpContext.Current.Session["file_" + thisFileKey].ToString();
                                if (possible_label.Length > 0)
                                    label = possible_label;
                            }

                            // Add this file
                            Item_To_Complete.Divisions.Physical_Tree.Add_File(newFile, label);

                            // Seperate code for JP2 and JPEG type files
                            string extension = fileInfo.Extension.ToUpper();
                            if (extension.IndexOf("JP2") >= 0)
                            {
                                if (!error_reading_file_occurred)
                                {
                                    if (!newFile.Compute_Jpeg2000_Attributes(userInProcessDirectory))
                                        error_reading_file_occurred = true;
                                }
                                jp2_added = true;
                            }
                            else
                            {
                                if (!error_reading_file_occurred)
                                {
                                    if (!newFile.Compute_Jpeg_Attributes(userInProcessDirectory))
                                        error_reading_file_occurred = true;
                                }
                                jpeg_added = true;
                            }
                        }
                    }

                    // Add the download files next
                    foreach(string thisFileKey in download_files.Keys )
                    {
                        // Get the list of files
                        List<string> theseFiles = download_files[thisFileKey];

                        // Add each file
                        foreach (string thisFile in theseFiles)
                        {
                            // Create the new file object and compute a label
                            FileInfo fileInfo = new FileInfo(thisFile);
                            SobekCM_File_Info newFile = new SobekCM_File_Info(fileInfo.Name);
                            string label = fileInfo.Name.Replace( fileInfo.Extension, "");
                            if (HttpContext.Current.Session["file_" + thisFileKey] != null)
                            {
                                string possible_label = HttpContext.Current.Session["file_" + thisFileKey].ToString();
                                if (possible_label.Length > 0)
                                    label = possible_label;
                            }

                            // Add this file
                            Item_To_Complete.Divisions.Download_Tree.Add_File(newFile, label);
                        }
                    }

                    // Add the JPEG2000 and JPEG-specific viewers
                    Item_To_Complete.Behaviors.Clear_Views();
                    if (jpeg_added)
                    {
                        Item_To_Complete.Behaviors.Add_View(View_Enum.JPEG);
                    }
                    if (jp2_added)
                    {
                        Item_To_Complete.Behaviors.Add_View(View_Enum.JPEG2000);
                    }
                }

                // Determine the total size of the package before saving
                string[] all_files_final = Directory.GetFiles(userInProcessDirectory);
                double size = all_files_final.Aggregate<string, double>(0, (Current, ThisFile) => Current + (((new FileInfo(ThisFile)).Length)/1024));
                Item_To_Complete.DiskSize_KB = size;

                // BibID and VID will be automatically assigned
                Item_To_Complete.BibID = completeTemplate.BibID_Root;
                Item_To_Complete.VID = String.Empty;

                // Set some values in the tracking portion
                if (Item_To_Complete.Divisions.Files.Count > 0)
                {
                    Item_To_Complete.Tracking.Born_Digital = true;
                }
                Item_To_Complete.Tracking.VID_Source = "SobekCM:" + templateCode;

                // If this is a dataset and XML file was uploaded, add some viewers
                if ((xml_found) && (Item_To_Complete.Bib_Info.SobekCM_Type == TypeOfResource_SobekCM_Enum.Dataset))
                {
                    Item_To_Complete.Behaviors.Add_View(View_Enum.DATASET_CODEBOOK);
                    Item_To_Complete.Behaviors.Add_View(View_Enum.DATASET_REPORTS);
                    Item_To_Complete.Behaviors.Add_View(View_Enum.DATASET_VIEWDATA);
                }

                // Save to the database
                try
                {
                    Resource_Object.Database.SobekCM_Database.Save_New_Digital_Resource(Item_To_Complete, false, true, RequestSpecificValues.Current_User.UserName, String.Empty, RequestSpecificValues.Current_User.UserID);
                }
                catch (Exception ee)
                {
                    StreamWriter writer = new StreamWriter(userInProcessDirectory + "\\exception.txt", false);
                    writer.WriteLine( "ERROR CAUGHT WHILE SAVING NEW DIGITAL RESOURCE");
                    writer.WriteLine( DateTime.Now.ToString());
                    writer.WriteLine();
                    writer.WriteLine( ee.Message );
                    writer.WriteLine( ee.StackTrace );
                    writer.Flush();
                    writer.Close();
                    throw;
                }

                // Assign the file root and assoc file path
                Item_To_Complete.Web.File_Root = Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8, 2);
                Item_To_Complete.Web.AssocFilePath = Item_To_Complete.Web.File_Root + "\\" + Item_To_Complete.VID + "\\";

                // Create the static html pages
                string base_url = RequestSpecificValues.Current_Mode.Base_URL;
                try
                {
                    Static_Pages_Builder staticBuilder = new Static_Pages_Builder(UI_ApplicationCache_Gateway.Settings.Servers.System_Base_URL, UI_ApplicationCache_Gateway.Settings.Servers.Base_Data_Directory, RequestSpecificValues.HTML_Skin.Skin_Code);
                    string filename = userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html";
                    staticBuilder.Create_Item_Citation_HTML(Item_To_Complete, filename, String.Empty);

                    // Copy the static HTML file to the web server
                    try
                    {
                        if (!Directory.Exists(UI_ApplicationCache_Gateway.Settings.Servers.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8)))
                            Directory.CreateDirectory(UI_ApplicationCache_Gateway.Settings.Servers.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8));
                        if (File.Exists(userInProcessDirectory + "\\" + item.BibID + "_" + item.VID + ".html"))
                            File.Copy(userInProcessDirectory + "\\" + item.BibID + "_" + item.VID + ".html", UI_ApplicationCache_Gateway.Settings.Servers.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8) + "\\" + item.BibID + "_" + item.VID + ".html", true);
                    }
                    catch (Exception)
                    {
                        // This is not critical
                    }
                }
                catch (Exception)
                {
                    // An error here is not catastrophic
                }

                RequestSpecificValues.Current_Mode.Base_URL = base_url;

                // Save the rest of the metadata
                Item_To_Complete.Save_SobekCM_METS();

                // Add this to the cache
                UI_ApplicationCache_Gateway.Items.Add_SobekCM_Item(Item_To_Complete);

                // Create the options dictionary used when saving information to the database, or writing MarcXML
                Dictionary<string, object> options = new Dictionary<string, object>();
                if (UI_ApplicationCache_Gateway.Settings.MarcGeneration != null)
                {
                    options["MarcXML_File_ReaderWriter:MARC Cataloging Source Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Cataloging_Source_Code;
                    options["MarcXML_File_ReaderWriter:MARC Location Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Location_Code;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Agency"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Agency;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Place"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Place;
                    options["MarcXML_File_ReaderWriter:MARC XSLT File"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.XSLT_File;
                }
                options["MarcXML_File_ReaderWriter:System Name"] = UI_ApplicationCache_Gateway.Settings.System.System_Name;
                options["MarcXML_File_ReaderWriter:System Abbreviation"] = UI_ApplicationCache_Gateway.Settings.System.System_Abbreviation;

                // Save the marc xml file
                MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                string errorMessage;
                marcWriter.Write_Metadata(Item_To_Complete.Source_Directory + "\\marc.xml", Item_To_Complete, options, out errorMessage);

                // Delete the TEMP mets file
                if (File.Exists(userInProcessDirectory + "\\TEMP000001_00001.mets"))
                    File.Delete(userInProcessDirectory + "\\TEMP000001_00001.mets");

                // Rename the METS file to the XML file
                if ((!File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets.xml")) &&
                    (File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets")))
                {
                    File.Move(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets", userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets.xml");
                }

                string serverNetworkFolder = UI_ApplicationCache_Gateway.Settings.Servers.Image_Server_Network + Item_To_Complete.Web.AssocFilePath;

                // Create the folder
                if (!Directory.Exists(serverNetworkFolder))
                    Directory.CreateDirectory(serverNetworkFolder);
                if (!Directory.Exists(serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name))
                    Directory.CreateDirectory(serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name);

                // Copy the static HTML page over first
                if (File.Exists(userInProcessDirectory + "\\" + item.BibID + "_" + item.VID + ".html"))
                {
                    File.Copy(userInProcessDirectory + "\\" + item.BibID + "_" + item.VID + ".html", serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name + "\\" + item.BibID + "_" + item.VID + ".html", true);
                    File.Delete(userInProcessDirectory + "\\" + item.BibID + "_" + item.VID + ".html");
                }

                // Copy all the files
                string[] allFiles = Directory.GetFiles(userInProcessDirectory);
                foreach (string thisFile in allFiles)
                {
                    string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                    File.Copy(thisFile, destination_file, true);
                }

                // Add this to the cache
                UI_ApplicationCache_Gateway.Items.Add_SobekCM_Item(Item_To_Complete);

                // Incrememnt the count of number of items submitted by this RequestSpecificValues.Current_User
                RequestSpecificValues.Current_User.Items_Submitted_Count++;
                if (!RequestSpecificValues.Current_User.BibIDs.Contains(Item_To_Complete.BibID))
                    RequestSpecificValues.Current_User.Add_BibID(Item_To_Complete.BibID);

                // Now, delete all the files here
                all_files = Directory.GetFiles(userInProcessDirectory);
                foreach (string thisFile in all_files)
                {
                    File.Delete(thisFile);
                }

                // Finally, set the item for more processing if there were any files
                if (((image_files.Count > 0) || (download_files.Count > 0)) && ( Item_To_Complete.Web.ItemID > 0 ))
                {
                    SobekCM_Database.Update_Additional_Work_Needed_Flag(Item_To_Complete.Web.ItemID, true, Tracer);
                }

                // Clear any temporarily assigned current project and CompleteTemplate
                RequestSpecificValues.Current_User.Current_Default_Metadata = null;
                RequestSpecificValues.Current_User.Current_Template = null;

            }
            catch (Exception ee)
            {
                validationErrors.Add("Error encountered during item save!");
                validationErrors.Add(ee.ToString().Replace("\r", "<br />"));

                // Set an initial flag
                criticalErrorEncountered = true;

                string error_body = "<strong>ERROR ENCOUNTERED DURING ONLINE SUBMITTAL PROCESS</strong><br /><br /><blockquote>Title: " + Item_To_Complete.Bib_Info.Main_Title.Title + "<br />Permanent Link: <a href=\"" + RequestSpecificValues.Current_Mode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "\">" + RequestSpecificValues.Current_Mode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "</a><br />User: "******"<br /><br /></blockquote>" + ee.ToString().Replace("\n", "<br />");
                string error_subject = "Error during submission for '" + Item_To_Complete.Bib_Info.Main_Title.Title + "'";
                string email_to = UI_ApplicationCache_Gateway.Settings.Email.System_Error_Email;
                if (email_to.Length == 0)
                    email_to = UI_ApplicationCache_Gateway.Settings.Email.System_Email;
                Email_Helper.SendEmail(email_to, error_subject, error_body, true, RequestSpecificValues.Current_Mode.Instance_Name);
            }

            if (!criticalErrorEncountered)
            {
                // Send email to the email from the CompleteTemplate, if one was provided
                if (completeTemplate.Email_Upon_Receipt.Length > 0)
                {
                    string body = "New item submission complete!<br /><br /><blockquote>Title: " + Item_To_Complete.Bib_Info.Main_Title.Title + "<br />Submittor: " + RequestSpecificValues.Current_User.Full_Name + " ( " + RequestSpecificValues.Current_User.Email + " )<br />Link: <a href=\"" + RequestSpecificValues.Current_Mode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "\">" + Item_To_Complete.BibID + ":" + Item_To_Complete.VID + "</a></blockquote>";
                    string subject = "Item submission complete for '" + Item_To_Complete.Bib_Info.Main_Title.Title + "'";
                    Email_Helper.SendEmail(completeTemplate.Email_Upon_Receipt, subject, body, true, RequestSpecificValues.Current_Mode.Instance_Name);
                }

                // If the RequestSpecificValues.Current_User wants to have a message sent, send one
                if (RequestSpecificValues.Current_User.Send_Email_On_Submission)
                {
                    // Create the mail message
                    string body2 = "<strong>CONGRATULATIONS!</strong><br /><br />Your item has been successfully added to the digital library and will appear immediately.  Search indexes may take a couple minutes to build, at which time this item will be discoverable through the search interface. <br /><br /><blockquote>Title: " + Item_To_Complete.Bib_Info.Main_Title.Title + "<br />Permanent Link: <a href=\"" + RequestSpecificValues.Current_Mode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "\">" + RequestSpecificValues.Current_Mode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "</a></blockquote>";
                    string subject2 = "Item submission complete for '" + Item_To_Complete.Bib_Info.Main_Title.Title + "'";
                    Email_Helper.SendEmail(RequestSpecificValues.Current_User.Email, subject2, body2, true, RequestSpecificValues.Current_Mode.Instance_Name);
                }

                // Also clear any searches or browses ( in the future could refine this to only remove those
                // that are impacted by this save... but this is good enough for now )
                CachedDataManager.Clear_Search_Results_Browses();
            }

            return criticalErrorEncountered;
        }
 /// <summary> Reads the bibliographic information from an existing MARC XML file into the current object </summary>
 /// <param name="fileName">Name of the MARC XML file</param>
 public bool Read_From_MARC_XML(string fileName)
 {
     string errorMessage;
     MarcXML_File_ReaderWriter reader = new MarcXML_File_ReaderWriter();
     return reader.Read_Metadata(fileName, this, null, out errorMessage);
 }
 /// <summary> Reads the bibliographic information from an existing MARC XML file and returns a new object </summary>
 /// <param name="fileName">Name of the MARC XML file</param>
 /// <returns>Built SobekCM_Item object</returns>
 public static SobekCM_Item Read_MARC_XML(string fileName)
 {
     SobekCM_Item returnVal = new SobekCM_Item();
     string errorMessage;
     MarcXML_File_ReaderWriter reader = new MarcXML_File_ReaderWriter();
     reader.Read_Metadata(fileName, returnVal, null, out errorMessage);
     return returnVal;
 }
        private void Complete_Item_Save()
        {
            if (isProject)
            {
                // Save the new project METS
                item.Save_METS();

                // Clear the cache of this item
                Cached_Data_Manager.Remove_Project(user.UserID, item.BibID, null);

                // Redirect
                currentMode.Mode = Display_Mode_Enum.Administrative;
                currentMode.Admin_Type = Admin_Type_Enum.Default_Metadata;
                currentMode.My_Sobek_SubMode = String.Empty;
                currentMode.Redirect();
            }
            else
            {
                // Determine the in process directory for this
                string user_bib_vid_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.ShibbID + "\\metadata_updates\\" + item.BibID + "_" + item.VID;
                if (user.ShibbID.Trim().Length == 0)
                    user_bib_vid_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.UserName.Replace(".", "").Replace("@", "") + "\\metadata_updates\\" + item.BibID + "_" + item.VID;

                // Ensure the folder exists and is empty to start with
                if (!Directory.Exists(user_bib_vid_process_directory))
                    Directory.CreateDirectory(user_bib_vid_process_directory);
                else
                {
                    // Anything older than a day should be deleted
                    string[] files = Directory.GetFiles(user_bib_vid_process_directory);
                    foreach (string thisFile in files)
                    {
                        try
                        {
                            File.Delete(thisFile);
                        }
                        catch (Exception)
                        {
                            // Not much to do here
                        }
                    }
                }

                // Update the METS file with METS note and name
                item.METS_Header.Creator_Individual = user.UserName;
                item.METS_Header.Modify_Date = DateTime.Now;
                item.METS_Header.RecordStatus_Enum = METS_Record_Status.METADATA_UPDATE;

                // Save the METS file and related items
                bool successful_save = true;
                try
                {
                    SobekCM_Database.Save_Digital_Resource(item, DateTime.Now, true);
                }
                catch
                {
                    successful_save = false;
                }

                // Create the static html pages
                string base_url = currentMode.Base_URL;
                try
                {
                    Static_Pages_Builder staticBuilder = new Static_Pages_Builder(SobekCM_Library_Settings.System_Base_URL, SobekCM_Library_Settings.Base_Data_Directory, Translator, codeManager, iconList, skins, webSkin.Skin_Code);
                    string filename = user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html";
                    staticBuilder.Create_Item_Citation_HTML(item, filename, SobekCM_Library_Settings.Image_Server_Network + item.Web.AssocFilePath);

                    // Copy the static HTML file to the web server
                    try
                    {
                        if (!Directory.Exists(SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8)))
                            Directory.CreateDirectory(SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8));
                        if (File.Exists(user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html"))
                            File.Copy(user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html", SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8) + "\\" + item.BibID + "_" + item.VID + ".html", true);
                    }
                    catch
                    {
                        // This is not critical
                    }
                }
                catch
                {
                    // Failing to make the static page is not the worst thing in the world...
                }

                currentMode.Base_URL = base_url;

                item.Source_Directory = user_bib_vid_process_directory;
                item.Save_SobekCM_METS();

                // If this was not able to be saved in the database, try it again
                if (!successful_save)
                {
                    SobekCM_Database.Save_Digital_Resource(item, DateTime.Now, false);
                }

                // Make sure the progress has been added to this item's work log
                try
                {
                    Database.SobekCM_Database.Tracking_Online_Edit_Complete(item.Web.ItemID, user.Full_Name, String.Empty);
                }
                catch(Exception)
                {
                    // This is not critical
                }

                // Save the MARC file
                List<string> collectionnames = new List<string>();
                MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                string errorMessage;
                Dictionary<string, object> options = new Dictionary<string, object>();
                options["MarcXML_File_ReaderWriter:Additional_Tags"] = item.MARC_Sobek_Standard_Tags(collectionnames, true, SobekCM_Library_Settings.System_Name, SobekCM_Library_Settings.System_Abbreviation);
                marcWriter.Write_Metadata(item.Source_Directory + "\\marc.xml", item, options, out errorMessage);

                // Copy this to all the image servers
                SobekCM_Library_Settings.Refresh(Database.SobekCM_Database.Get_Settings_Complete(null));

                // Determine the server folder
                string serverNetworkFolder = SobekCM_Library_Settings.Image_Server_Network + item.Web.AssocFilePath;

                // Create the folder
                if (!Directory.Exists(serverNetworkFolder))
                {
                    Directory.CreateDirectory(serverNetworkFolder);
                    if (!Directory.Exists(serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME))
                        Directory.CreateDirectory(serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME);
                }
                else
                {
                    if (!Directory.Exists(serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME))
                        Directory.CreateDirectory(serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME);

                    // Rename any existing standard mets to keep a backup
                    if (File.Exists(serverNetworkFolder + "\\" + item.BibID + "_" + item.VID + ".mets.xml"))
                    {
                        FileInfo currentMetsFileInfo = new FileInfo(serverNetworkFolder + "\\" + item.BibID + "_" + item.VID + ".mets.xml");
                        DateTime lastModDate = currentMetsFileInfo.LastWriteTime;
                        File.Copy(serverNetworkFolder + "\\" + item.BibID + "_" + item.VID + ".mets.xml", serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME + "\\" + item.BibID + "_" + item.VID + "_" + lastModDate.Year + "_" + lastModDate.Month + "_" + lastModDate.Day + ".mets.bak", true);
                    }
                }

                // Copy the static HTML page over first
                if (File.Exists(user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html"))
                {
                    File.Copy(user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html", serverNetworkFolder + "\\" + SobekCM_Library_Settings.BACKUP_FILES_FOLDER_NAME + "\\" + item.BibID + "_" + item.VID + ".html", true);
                    File.Delete(user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html");
                }

                // Copy all the files
                string[] allFiles = Directory.GetFiles(user_bib_vid_process_directory);
                foreach (string thisFile in allFiles)
                {
                    string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                    File.Copy(thisFile, destination_file, true);
                }

                // Add this to the cache
                itemList.Add_SobekCM_Item(item, false);

                // Now, delete all the files here
                string[] all_files = Directory.GetFiles(user_bib_vid_process_directory);
                foreach (string thisFile in all_files)
                {
                    try
                    {
                        File.Delete(thisFile);
                    }
                    catch
                    {

                    }
                }

                // Clear the user-specific and global cache of this item
                Cached_Data_Manager.Remove_Digital_Resource_Object(user.UserID, item.BibID, item.VID, null);
                Cached_Data_Manager.Remove_Digital_Resource_Object(item.BibID, item.VID, null);
                Cached_Data_Manager.Remove_Items_In_Title(item.BibID, null);

                // Forward to the display item again
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.ViewerCode = "citation";
                currentMode.Redirect();
            }
        }
        /// <summary> Update the exsting digital resource, by saving the changes to the database and rewriting metadata files </summary>
        /// <param name="Item"> Digital resource object with all the updated metadata </param>
        /// <param name="User"> User who performed the update, for the item milestones </param>
        /// <param name="Error_Message"> [OUT] Return an error message if an exception is encountered </param>
        /// <returns> TRUE if successful, otherwise FALSE </returns>
        public static bool Update_Item(SobekCM_Item Item, User_Object User, out string Error_Message )
        {
            Error_Message = String.Empty;

            // Determine the in process directory for this
            string user_bib_vid_process_directory = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.In_Process_Submission_Location, User.ShibbID + "\\metadata_updates\\" + Item.BibID + "_" + Item.VID);
            if (User.ShibbID.Trim().Length == 0)
                user_bib_vid_process_directory = Path.Combine(Engine_ApplicationCache_Gateway.Settings.Servers.In_Process_Submission_Location, User.UserName.Replace(".", "").Replace("@", "") + "\\metadata_updates\\" + Item.BibID + "_" + Item.VID);

            // Ensure the folder exists and is empty to start with
            if (!Directory.Exists(user_bib_vid_process_directory))
                Directory.CreateDirectory(user_bib_vid_process_directory);
            else
            {
                // Anything older than a day should be deleted
                string[] files = Directory.GetFiles(user_bib_vid_process_directory);
                foreach (string thisFile in files)
                {
                    try
                    {
                        File.Delete(thisFile);
                    }
                    catch (Exception)
                    {
                        // Not much to do here
                    }
                }
            }

            // Update the METS file with METS note and name
            Item.METS_Header.Creator_Individual = User.UserName;
            Item.METS_Header.Modify_Date = DateTime.Now;
            Item.METS_Header.RecordStatus_Enum = METS_Record_Status.METADATA_UPDATE;

            // Create the options dictionary used when saving information to the database, or writing MarcXML
            Dictionary<string, object> options = new Dictionary<string, object>();
            if (Engine_ApplicationCache_Gateway.Settings.MarcGeneration != null)
            {
                options["MarcXML_File_ReaderWriter:MARC Cataloging Source Code"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Cataloging_Source_Code;
                options["MarcXML_File_ReaderWriter:MARC Location Code"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Location_Code;
                options["MarcXML_File_ReaderWriter:MARC Reproduction Agency"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Agency;
                options["MarcXML_File_ReaderWriter:MARC Reproduction Place"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Place;
                options["MarcXML_File_ReaderWriter:MARC XSLT File"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.XSLT_File;
            }
            options["MarcXML_File_ReaderWriter:System Name"] = Engine_ApplicationCache_Gateway.Settings.System.System_Name;
            options["MarcXML_File_ReaderWriter:System Abbreviation"] = Engine_ApplicationCache_Gateway.Settings.System.System_Abbreviation;
            //  options["MarcXML_File_ReaderWriter:Additional_Tags"] = Item.MARC_Sobek_Standard_Tags(true, Engine_ApplicationCache_Gateway.Settings.System.System_Name, Engine_ApplicationCache_Gateway.Settings.System.System_Abbreviation);

            // Save the METS file and related Items
            bool successful_save = true;
            try
            {
                SobekCM_Database.Save_Digital_Resource(Item, options, DateTime.Now, true);
            }
            catch
            {
                successful_save = false;
            }

            //// Create the static html pages
            //string base_url = RequestSpecificValues.Current_Mode.Base_URL;
            //try
            //{
            //    Static_Pages_Builder staticBuilder = new Static_Pages_Builder(Engine_AppliationCache_Gateway.Settings.Servers.System_Base_URL, Engine_AppliationCache_Gateway.Settings.Servers.Base_Data_Directory, RequestSpecificValues.HTML_Skin.Skin_Code);
            //    string filename = user_bib_vid_process_directory + "\\" + Item.BibID + "_" + Item.VID + ".html";
            //    staticBuilder.Create_Item_Citation_HTML(Item, filename, Engine_AppliationCache_Gateway.Settings.Servers.Image_Server_Network + Item.Web.AssocFilePath);

            //    // Copy the static HTML file to the web server
            //    try
            //    {
            //        if (!Directory.Exists(Engine_AppliationCache_Gateway.Settings.Servers.Static_Pages_Location + Item.BibID.Substring(0, 2) + "\\" + Item.BibID.Substring(2, 2) + "\\" + Item.BibID.Substring(4, 2) + "\\" + Item.BibID.Substring(6, 2) + "\\" + Item.BibID.Substring(8)))
            //            Directory.CreateDirectory(Engine_AppliationCache_Gateway.Settings.Servers.Static_Pages_Location + Item.BibID.Substring(0, 2) + "\\" + Item.BibID.Substring(2, 2) + "\\" + Item.BibID.Substring(4, 2) + "\\" + Item.BibID.Substring(6, 2) + "\\" + Item.BibID.Substring(8));
            //        if (File.Exists(user_bib_vid_process_directory + "\\" + Item.BibID + "_" + Item.VID + ".html"))
            //            File.Copy(user_bib_vid_process_directory + "\\" + Item.BibID + "_" + Item.VID + ".html", Engine_AppliationCache_Gateway.Settings.Servers.Static_Pages_Location + Item.BibID.Substring(0, 2) + "\\" + Item.BibID.Substring(2, 2) + "\\" + Item.BibID.Substring(4, 2) + "\\" + Item.BibID.Substring(6, 2) + "\\" + Item.BibID.Substring(8) + "\\" + Item.BibID + "_" + Item.VID + ".html", true);
            //    }
            //    catch
            //    {
            //        // This is not critical
            //    }
            //}
            //catch
            //{
            //    // Failing to make the static page is not the worst thing in the world...
            //}
            //RequestSpecificValues.Current_Mode.Base_URL = base_url;

            Item.Source_Directory = user_bib_vid_process_directory;
            Item.Save_SobekCM_METS();

            // If this was not able to be saved in the database, try it again
            if (!successful_save)
            {
                SobekCM_Database.Save_Digital_Resource(Item, options, DateTime.Now, false);
            }

            // Make sure the progress has been added to this Item's work log
            try
            {
                Engine_Database.Tracking_Online_Edit_Complete(Item.Web.ItemID, User.Full_Name, String.Empty);
            }
            catch (Exception)
            {
                // This is not critical
            }

            // Save the MARC file
            MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
            string errorMessage;
            marcWriter.Write_Metadata(Item.Source_Directory + "\\marc.xml", Item, options, out errorMessage);

            // Determine the server folder
            string serverNetworkFolder = Engine_ApplicationCache_Gateway.Settings.Servers.Image_Server_Network + Item.Web.AssocFilePath;

            // Create the folder
            if (!Directory.Exists(serverNetworkFolder))
            {
                Directory.CreateDirectory(serverNetworkFolder);
                if (!Directory.Exists(serverNetworkFolder + "\\" + Engine_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name))
                    Directory.CreateDirectory(serverNetworkFolder + "\\" + Engine_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name);
            }
            else
            {
                if (!Directory.Exists(serverNetworkFolder + "\\" + Engine_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name))
                    Directory.CreateDirectory(serverNetworkFolder + "\\" + Engine_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name);

                // Rename any existing standard mets to keep a backup
                if (File.Exists(serverNetworkFolder + "\\" + Item.BibID + "_" + Item.VID + ".mets.xml"))
                {
                    FileInfo currentMetsFileInfo = new FileInfo(serverNetworkFolder + "\\" + Item.BibID + "_" + Item.VID + ".mets.xml");
                    DateTime lastModDate = currentMetsFileInfo.LastWriteTime;
                    File.Copy(serverNetworkFolder + "\\" + Item.BibID + "_" + Item.VID + ".mets.xml", serverNetworkFolder + "\\" + Engine_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name + "\\" + Item.BibID + "_" + Item.VID + "_" + lastModDate.Year + "_" + lastModDate.Month + "_" + lastModDate.Day + ".mets.bak", true);
                }
            }

            // Copy the static HTML page over first
            if (File.Exists(user_bib_vid_process_directory + "\\" + Item.BibID + "_" + Item.VID + ".html"))
            {
                File.Copy(user_bib_vid_process_directory + "\\" + Item.BibID + "_" + Item.VID + ".html", serverNetworkFolder + "\\" + Engine_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name + "\\" + Item.BibID + "_" + Item.VID + ".html", true);
                File.Delete(user_bib_vid_process_directory + "\\" + Item.BibID + "_" + Item.VID + ".html");
            }

            // Copy all the files
            string[] allFiles = Directory.GetFiles(user_bib_vid_process_directory);
            foreach (string thisFile in allFiles)
            {
                string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                File.Copy(thisFile, destination_file, true);
            }

            // Add this to the cache
            Engine_ApplicationCache_Gateway.Items.Add_SobekCM_Item(Item, false);

            // Now, delete all the files here
            string[] all_files = Directory.GetFiles(user_bib_vid_process_directory);
            foreach (string thisFile in all_files)
            {
                try
                {
                    File.Delete(thisFile);
                }
                catch
                {

                }
            }

            // Clear the User-specific and global cache of this Item
            CachedDataManager.Remove_Digital_Resource_Object(User.UserID, Item.BibID, Item.VID, null);
            CachedDataManager.Remove_Digital_Resource_Object(Item.BibID, Item.VID, null);
            CachedDataManager.Remove_Items_In_Title(Item.BibID, null);

            // Also clear any searches or browses ( in the future could refine this to only remove those
            // that are impacted by this save... but this is good enough for now )
            CachedDataManager.Clear_Search_Results_Browses();

            return true;
        }
        /// <summary> Creates the static MarcXML file for a digital resource </summary>
        /// <param name="BIBID"> Bibliographic identifier ( BibID )</param>
        /// <param name="VID"> Volume identifier ( VID ) </param>
        /// <param name="DestinationDirectory"> Directory where the resultant MarcXML file should be written </param>
        /// <param name="Item_List"> Item lookup object </param>
        /// <returns>  This will read the currently live METS file and build the digital object with additional
        /// information from the database before writing the MarcXML file </returns>
        public bool Create_MarcXML_File(string BIBID, string VID, string DestinationDirectory, Item_Lookup_Object Item_List )
        {
            // Clear the current tracer
            tracer.Clear();

            try
            {

                // Set the item for the current mode
                currentMode.BibID = BIBID;
                currentMode.VID = VID;
                currentMode.ViewerCode = "citation";
                currentMode.Skin = "";
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.Language = Web_Language_Enum.English;
                currentMode.Trace_Flag = Trace_Flag_Type_Enum.No;

                // Get the item
                SobekCM_Item currentItem;
                Page_TreeNode currentPage;
                SobekCM_Items_In_Title itemsInTitle;
                assistant.Get_Item(String.Empty, currentMode, Item_List, UI_ApplicationCache_Gateway.Settings.Servers.Image_URL, UI_ApplicationCache_Gateway.Icon_List, null, tracer, null, out currentItem, out currentPage, out itemsInTitle);
                currentMode.Aggregation = String.Empty;
                if (currentItem == null)
                    return false;

                if (currentItem.Behaviors.Aggregation_Count > 0)
                    currentMode.Aggregation = currentItem.Behaviors.Aggregations[0].Code;

                string marcFile = DestinationDirectory + currentItem.Web.File_Root + "\\" + currentItem.VID + "\\marc.xml";

                // Create the options dictionary used when saving information to the database, or writing MarcXML
                Dictionary<string, object> options = new Dictionary<string, object>();
                if (UI_ApplicationCache_Gateway.Settings.MarcGeneration != null)
                {
                    options["MarcXML_File_ReaderWriter:MARC Cataloging Source Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Cataloging_Source_Code;
                    options["MarcXML_File_ReaderWriter:MARC Location Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Location_Code;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Agency"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Agency;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Place"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Place;
                    options["MarcXML_File_ReaderWriter:MARC XSLT File"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.XSLT_File;
                }
                options["MarcXML_File_ReaderWriter:System Name"] = UI_ApplicationCache_Gateway.Settings.System.System_Name;
                options["MarcXML_File_ReaderWriter:System Abbreviation"] = UI_ApplicationCache_Gateway.Settings.System.System_Abbreviation;

                MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                string errorMessage;
                return marcWriter.Write_Metadata(marcFile, currentItem, options, out errorMessage);
            }
            catch
            {
                return false;
            }
        }
        /// <summary> Get the item in a standard XML format, such as dublin core, marcxml, etc.. </summary>
        /// <param name="Response"></param>
        /// <param name="UrlSegments"></param>
        /// <param name="QueryString"></param>
        /// <param name="Protocol"></param>
        /// <param name="IsDebug"></param>
        public void GetItemXml(HttpResponse Response, List<string> UrlSegments, NameValueCollection QueryString, Microservice_Endpoint_Protocol_Enum Protocol, bool IsDebug)
        {
            if (Protocol == Microservice_Endpoint_Protocol_Enum.XML)
            {

                if (UrlSegments.Count > 1)
                {
                    Custom_Tracer tracer = new Custom_Tracer();

                    string format = UrlSegments[0];
                    string bibid = UrlSegments[1];
                    string vid = "00001";

                    if (UrlSegments.Count > 2)
                        vid = UrlSegments[2];

                    // Get the current item first
                    SobekCM_Item sobekItem = getSobekItem(bibid, vid, tracer);

                    // If null, return
                    if (sobekItem == null)
                        return;

                    string errorMessage;
                    switch (format.ToLower())
                    {
                        case "dc":
                            DC_File_ReaderWriter dcWriter = new DC_File_ReaderWriter();
                            dcWriter.Write_Metadata(Response.Output, sobekItem, null, out errorMessage);
                            break;

                        case "rdf":
                            Dictionary<string, object> options_rdf = new Dictionary<string, object>();
                            options_rdf["DC_File_ReaderWriter:RDF_Style"] = true;
                            DC_File_ReaderWriter rdfWriter = new DC_File_ReaderWriter();
                            rdfWriter.Write_Metadata(Response.Output, sobekItem, options_rdf, out errorMessage);
                            break;

                        case "mods":
                            MODS_File_ReaderWriter modsWriter = new MODS_File_ReaderWriter();
                            modsWriter.Write_Metadata(Response.Output, sobekItem, null, out errorMessage);
                            break;

                        case "marc":

                            // Create the options dictionary used when saving information to the database, or writing MarcXML
                            Dictionary<string, object> options = new Dictionary<string, object>();
                            if (Engine_ApplicationCache_Gateway.Settings.MarcGeneration != null)
                            {
                                options["MarcXML_File_ReaderWriter:MARC Cataloging Source Code"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Cataloging_Source_Code;
                                options["MarcXML_File_ReaderWriter:MARC Location Code"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Location_Code;
                                options["MarcXML_File_ReaderWriter:MARC Reproduction Agency"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Agency;
                                options["MarcXML_File_ReaderWriter:MARC Reproduction Place"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Place;
                                options["MarcXML_File_ReaderWriter:MARC XSLT File"] = Engine_ApplicationCache_Gateway.Settings.MarcGeneration.XSLT_File;
                            }
                            options["MarcXML_File_ReaderWriter:System Name"] = Engine_ApplicationCache_Gateway.Settings.System.System_Name;
                            options["MarcXML_File_ReaderWriter:System Abbreviation"] = Engine_ApplicationCache_Gateway.Settings.System.System_Abbreviation;

                            MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                            marcWriter.Write_Metadata(Response.Output, sobekItem, options, out errorMessage);
                            break;
                    }
                }
            }
        }
        /// <summary> Creates the static MarcXML file for a digital resource </summary>
        /// <param name="BIBID"> Bibliographic identifier ( BibID )</param>
        /// <param name="VID"> Volume identifier ( VID ) </param>
        /// <param name="DestinationDirectory"> Directory where the resultant MarcXML file should be written </param>
        /// <param name="Item_List"> Item lookup object </param>
        /// <returns>  This will read the currently live METS file and build the digital object with additional
        /// information from the database before writing the MarcXML file </returns>
        public bool Create_MarcXML_File(string BIBID, string VID, string DestinationDirectory, Item_Lookup_Object Item_List )
        {
            // Clear the current tracer
            tracer.Clear();

            try
            {

                // Set the item for the current mode
                currentMode.BibID = BIBID;
                currentMode.VID = VID;
                currentMode.ViewerCode = "citation";
                currentMode.Skin = "";
                currentMode.Mode = Display_Mode_Enum.Item_Display;
                currentMode.Language = Web_Language_Enum.English;
                currentMode.Internal_User = false;
                currentMode.Trace_Flag = Trace_Flag_Type_Enum.No;

                // Get the item
                SobekCM_Item currentItem;
                Page_TreeNode currentPage;
                SobekCM_Items_In_Title itemsInTitle;
                assistant.Get_Item(String.Empty, currentMode, Item_List, SobekCM_Library_Settings.Image_URL, iconList, null, tracer, null, out currentItem, out currentPage, out itemsInTitle);
                currentMode.Aggregation = String.Empty;
                if (currentItem == null)
                    return false;

                if (currentItem.Behaviors.Aggregation_Count > 0)
                    currentMode.Aggregation = currentItem.Behaviors.Aggregations[0].Code;

                string marcFile = DestinationDirectory + currentItem.Web.File_Root + "\\" + currentItem.VID + "\\marc.xml";

                MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                string errorMessage;
                Dictionary<string, object> options = new Dictionary<string, object>();
                options["MarcXML_File_ReaderWriter:Additional_Tags"] = currentItem.MARC_Sobek_Standard_Tags(codeManager.Get_Collection_Short_Name(currentMode.Aggregation), true, SobekCM_Library_Settings.System_Name, SobekCM_Library_Settings.System_Abbreviation);
                return marcWriter.Write_Metadata(marcFile, currentItem, options, out errorMessage);
            }
            catch
            {
                return false;
            }
        }
        /// <summary> Do the bulk of the work of stepping through the input file and
        /// copying the data from the MARC record to the Tracking data object. </summary>
        public void Do_Work()
        {
            string username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            errors.Clear();
            errorCnt = 0;
            //int error = 0;

            // Declare the marc xml reader
            MarcXML_File_ReaderWriter marcReader = new MarcXML_File_ReaderWriter();

            try
            {
                // Read the first record
                MARC_Record result = parser.Parse( inputFile );

                // Loop through all the records
                while (parser.EOF_Flag == false)
                {
                    // Fire the event that one item is complete
                    OnNewProgress(recordsProcessed);

                    try
                    {
                        // check if the record is null or has errors
                        if (result == null)
                        {
                            // increment counters
                            errorCnt++;
                            recordsProcessed++;

                            // get next record
                            result = parser.Next();
                            continue;
                        }

                        // Save the MARC XML file
                        string marc_xml_file = Save_MARC_XML( result );

                        // If we should only save these, move on
                        if (JustSaveMarcXML)
                        {
                            recordsProcessed++;

                            // get next record
                            result = parser.Next();
                            continue;
                        }

                        // If there was no marc xml file saved, skip this and call it an error
                        if ((marc_xml_file.Length == 0) || (!File.Exists(marc_xml_file)))
                        {
                            // increment counters
                            errorCnt++;
                            recordsProcessed++;

                            // get next record
                            result = parser.Next();
                            continue;
                        }

                        // Load the information from the MARC XML file
                        SobekCM_Item newItem = new SobekCM_Item();
                        string error_message = String.Empty;
                        marcReader.Read_Metadata( marc_xml_file, newItem, null, out error_message );

                        // FOR THE MARC IMPORTER ONLY.. THE MAIN TITLE SHOULD BE COPIED TO THE BIB TITLE
                        if (newItem != null)
                        {
                            newItem.Behaviors.GroupTitle = newItem.Bib_Info.Main_Title.Title.Trim();
                        }

                        // try adding some data if the error flag is true
                        if ((result.Error_Flag) || ( newItem == null ))
                        {
                            // Add this to the result table being built
                            base.report.Add_Item(newItem, marc_xml_file, "Error reading MARC record");

                            // increment counters
                            errorCnt++;
                            recordsProcessed++;
                        }
                        else
                        {
                            // Copy all user settings to this package
                            base.Copy_User_Settings_To_Package(newItem);

                            // Save this to the tracking database
                            bool success = base.Check_For_Existence_And_Save(newItem, null, marc_xml_file, matching_message, "MARC Importer GUI", preview_mode);

                            // If that was successful, save a new METS file and add to item list
                            if (success)
                            {
                                // Save the METS
                                newItem.METS_Header.Creator_Software = "Spreadsheet Importer";
                                newItem.METS_Header.Creator_Individual = username;
                                save_to_mets(newItem, preview_mode);
                            }
                        }
                    }
                    catch (Exception ee)
                    {
                        DLC.Tools.Forms.ErrorMessageBox.Show(ee.Message, "DLC Importer Error", ee);
                        errorCnt++;
                    }

                    // Fire the event that one item is complete
                    OnNewProgress(recordsProcessed);

                    // Get the next one
                    result = parser.Next();
                }

                // display messagebox that import is complete
                if (preview_mode)
                {
                    MessageBox.Show("records processed:\t\t[ " + recordsProcessed.ToString("#,##0;") + " ]" +
                                    "\n\n records saved:\t\t[ " + recordsSavedToDB.ToString("#,##0;") + " ]" +
                                    "\n\n records skipped:\t\t[ " + recordsSkipped.ToString("#,##0;") + " ]" +
                                    "\n\n records with errors:\t[ " + errorCnt.ToString("#,##0;") + " ]", "Preview Complete!");
                }
                else
                {
                    MessageBox.Show("records processed:\t\t[ " + recordsProcessed.ToString("#,##0;") + " ]" +
                                    "\n\n records saved:\t\t[ " + recordsSavedToDB.ToString("#,##0;") + " ]" +
                                    "\n\n records skipped:\t\t[ " + recordsSkipped.ToString("#,##0;") + " ]" +
                                    "\n\n records with errors:\t[ " + errorCnt.ToString("#,##0;") + " ]", "Import Complete!");
                }

                recordsSavedToDB = 0;
            }
            catch (Exception ee)
            {
                MessageBox.Show("Error encountered while processing!     \n\nOnly " + recordsProcessed + " records processed.\n\n" + ee.ToString(), "Did not reach EOF Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning );
            }

            // Fire the event that the entire work is complete
            OnComplete(999999);
        }
        private bool complete_item_submission(SobekCM_Item Item_To_Complete,  Custom_Tracer Tracer )
        {
            // Set an initial flag
            criticalErrorEncountered = false;

            string[] all_files = Directory.GetFiles(userInProcessDirectory);
            SortedList<string, List<string>> image_files = new SortedList<string, List<string>>();
            SortedList<string, List<string>> download_files = new SortedList<string, List<string>>();
            foreach (string thisFile in all_files)
            {
                FileInfo thisFileInfo = new FileInfo(thisFile);

                if ((thisFileInfo.Name.IndexOf("agreement.txt") != 0) && (thisFileInfo.Name.IndexOf("TEMP000001_00001.mets") != 0) && (thisFileInfo.Name.IndexOf("doc.xml") != 0) && (thisFileInfo.Name.IndexOf("ufdc_mets.xml") != 0) && (thisFileInfo.Name.IndexOf("marc.xml") != 0))
                {
                    // Get information about this files name and extension
                    string extension_upper = thisFileInfo.Extension.ToUpper();
                    string filename_sans_extension = thisFileInfo.Name.Replace(thisFileInfo.Extension, "");
                    string name_upper = thisFileInfo.Name.ToUpper();

                    // Is this a page image?
                    if ((extension_upper == ".JPG") || (extension_upper == ".TIF") || (extension_upper == ".JP2") || (extension_upper == ".JPX"))
                    {
                        // Exclude .QC.jpg files
                        if (name_upper.IndexOf(".QC.JPG") < 0)
                        {
                            // If this is a thumbnail, trim off the THM part on the file name
                            if (name_upper.IndexOf("THM.JPG") > 0)
                            {
                                filename_sans_extension = filename_sans_extension.Substring(0, filename_sans_extension.Length - 3);
                            }

                            // Is this the first image file with this name?
                            if (image_files.ContainsKey(filename_sans_extension.ToLower()))
                            {
                                image_files[filename_sans_extension.ToLower()].Add(thisFileInfo.Name);
                            }
                            else
                            {
                                List<string> newImageGrouping = new List<string> {thisFileInfo.Name};
                                image_files[filename_sans_extension.ToLower()] = newImageGrouping;
                            }
                        }
                    }
                    else
                    {
                        // If this does not match the exclusion regular expression, than add this
                        if (!Regex.Match(thisFileInfo.Name, SobekCM_Library_Settings.Files_To_Exclude_From_Downloads, RegexOptions.IgnoreCase).Success)
                        {
                            // Is this the first image file with this name?
                            if (download_files.ContainsKey(filename_sans_extension.ToLower()))
                            {
                                download_files[filename_sans_extension.ToLower()].Add(thisFileInfo.Name);
                            }
                            else
                            {
                                List<string> newDownloadGrouping = new List<string> {thisFileInfo.Name};
                                download_files[filename_sans_extension.ToLower()] = newDownloadGrouping;
                            }
                        }
                    }
                }
            }

            // This package is good to go, so build it, save, etc...
            try
            {
                // Save the METS file to the database and back to the directory
                Item_To_Complete.Source_Directory = userInProcessDirectory;

                // Step through and add each file
                Item_To_Complete.Divisions.Download_Tree.Clear();
                if ((template.Upload_Types == Template.Template_Upload_Types.File_or_URL) || (template.Upload_Types == Template.Template_Upload_Types.File))
                {
                    // Step through each file

                    bool error_reading_file_occurred = false;

                    // Add the image files first
                    bool jpeg_added = false;
                    bool jp2_added = false;
                    foreach(string thisFileKey in image_files.Keys )
                    {
                        // Get the list of files
                        List<string> theseFiles = image_files[thisFileKey];

                        // Add each file
                        foreach (string thisFile in theseFiles)
                        {
                            // Create the new file object and compute a label
                            FileInfo fileInfo = new FileInfo(thisFile);
                            SobekCM_File_Info newFile = new SobekCM_File_Info(fileInfo.Name);
                            string label = fileInfo.Name.Replace(fileInfo.Extension, "");
                            if (HttpContext.Current.Session["file_" + thisFileKey] != null)
                            {
                                string possible_label = HttpContext.Current.Session["file_" + thisFileKey].ToString();
                                if (possible_label.Length > 0)
                                    label = possible_label;
                            }

                            // Add this file
                            Item_To_Complete.Divisions.Physical_Tree.Add_File(newFile, label);

                            // Seperate code for JP2 and JPEG type files
                            string extension = fileInfo.Extension.ToUpper();
                            if (extension.IndexOf("JP2") >= 0)
                            {
                                if (!error_reading_file_occurred)
                                {
                                    if (!newFile.Compute_Jpeg2000_Attributes(userInProcessDirectory))
                                        error_reading_file_occurred = true;
                                }
                                jp2_added = true;
                            }
                            else
                            {
                                if (!error_reading_file_occurred)
                                {
                                    if (!newFile.Compute_Jpeg_Attributes(userInProcessDirectory))
                                        error_reading_file_occurred = true;
                                }
                                jpeg_added = true;
                            }
                        }
                    }

                    // Add the download files next
                    foreach(string thisFileKey in download_files.Keys )
                    {
                        // Get the list of files
                        List<string> theseFiles = download_files[thisFileKey];

                        // Add each file
                        foreach (string thisFile in theseFiles)
                        {
                            // Create the new file object and compute a label
                            FileInfo fileInfo = new FileInfo(thisFile);
                            SobekCM_File_Info newFile = new SobekCM_File_Info(fileInfo.Name);
                            string label = fileInfo.Name.Replace( fileInfo.Extension, "");
                            if (HttpContext.Current.Session["file_" + thisFileKey] != null)
                            {
                                string possible_label = HttpContext.Current.Session["file_" + thisFileKey].ToString();
                                if (possible_label.Length > 0)
                                    label = possible_label;
                            }

                            // Add this file
                            Item_To_Complete.Divisions.Download_Tree.Add_File(newFile, label);
                        }
                    }

                    // Add the JPEG2000 and JPEG-specific viewers
                    Item_To_Complete.Behaviors.Clear_Views();
                    if (jpeg_added)
                    {
                        Item_To_Complete.Behaviors.Add_View(View_Enum.JPEG);
                    }
                    if (jp2_added)
                    {
                        Item_To_Complete.Behaviors.Add_View(View_Enum.JPEG2000);
                    }
                }

                // Determine the total size of the package before saving
                string[] all_files_final = Directory.GetFiles(userInProcessDirectory);
                double size = all_files_final.Aggregate<string, double>(0, (current, thisFile) => current + (((new FileInfo(thisFile)).Length)/1024));
                Item_To_Complete.DiskSize_MB = size;

                // BibID and VID will be automatically assigned
                Item_To_Complete.BibID = template.BibID_Root;
                Item_To_Complete.VID = String.Empty;

                // Set some values in the tracking portion
                if (Item_To_Complete.Divisions.Files.Count > 0)
                {
                    Item_To_Complete.Tracking.Born_Digital = true;
                }
                Item_To_Complete.Tracking.VID_Source = "SobekCM:" + templateCode;

                // Save to the database
                try
                {
                    SobekCM_Database.Save_New_Digital_Resource(Item_To_Complete, false, true, user.UserName, String.Empty, user.UserID);
                }
                catch (Exception ee)
                {
                    StreamWriter writer = new StreamWriter(userInProcessDirectory + "\\exception.txt", false);
                    writer.WriteLine( "ERROR CAUGHT WHILE SAVING NEW DIGITAL RESOURCE");
                    writer.WriteLine( DateTime.Now.ToString());
                    writer.WriteLine();
                    writer.WriteLine( ee.Message );
                    writer.WriteLine( ee.StackTrace );
                    writer.Flush();
                    writer.Close();
                    throw;
                }

                // Assign the file root and assoc file path
                Item_To_Complete.Web.File_Root = Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8, 2);
                Item_To_Complete.Web.AssocFilePath = Item_To_Complete.Web.File_Root + "\\" + Item_To_Complete.VID + "\\";

                // Create the static html pages
                string base_url = currentMode.Base_URL;
                try
                {
                    Static_Pages_Builder staticBuilder = new Static_Pages_Builder(SobekCM_Library_Settings.System_Base_URL, SobekCM_Library_Settings.Base_Data_Directory, Translator, codeManager, itemList, iconList, webSkin);
                    string filename = userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html";
                    staticBuilder.Create_Item_Citation_HTML(Item_To_Complete, filename, String.Empty);
                }
                catch (Exception)
                {
                    // An error here is not catastrophic
                }

                currentMode.Base_URL = base_url;

                // Save the rest of the metadata
                Item_To_Complete.Save_SobekCM_METS();
                Item_To_Complete.Save_Citation_Only_METS();

                // Add this to the cache
                itemList.Add_SobekCM_Item(Item_To_Complete);

                //// Link this item and user
                //Database.SobekCM_Database.Add_User_Item_Link(user.UserID, item.Web.ItemID, 1, true);
                //Database.SobekCM_Database.Add_User_BibID_Link(user.UserID, item.Behaviors.GroupID);
                //Database.SobekCM_Database.Add_Item_To_User_Folder(user.UserID, "Submitted Items", item.BibID, item.VID, 0, String.Empty, Tracer);

                // Save Bib_Level METS?
                //SobekCM.Resource_Object.Writers.OAI_Writer oaiWriter = new SobekCM.Resource_Object.Writers.OAI_Writer();
                //oaiWriter.Save_OAI_File(bibPackage, resource_folder + "\\oai_dc.xml", bibPackage.Processing_Parameters.Collection_Primary.ToLower(), createDate);

                List<string> collectionnames = new List<string>();
                //// Get the collection names
                //if (item.Processing_Parameters.Collection_Primary.Length > 0)
                //{
                //    DataRow[] primCode = Collection_Codes.Select("collectioncode = '" + item.Processing_Parameters.Collection_Primary + "'");
                //    if (primCode.Length > 0)
                //    {
                //        collectionnames.Add(primCode[0]["ShortName"].ToString());
                //    }
                //}
                //foreach (string altCollection in bibPackage.Processing_Parameters.Collections_Alternate)
                //{
                //    DataRow[] altCode = Collection_Codes.Select("collectioncode = '" + altCollection + "'");
                //    if (altCode.Length > 0)
                //    {
                //        collectionnames.Add(altCode[0]["ShortName"].ToString());
                //    }
                //}
                // Save the marc xml file
                MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                string Error_Message;
                Dictionary<string, object> options = new Dictionary<string, object>();
                options["MarcXML_File_ReaderWriter:Additional_Tags"] = Item_To_Complete.MARC_Sobek_Standard_Tags(collectionnames, true, SobekCM_Library_Settings.System_Name, SobekCM_Library_Settings.System_Abbreviation);
                marcWriter.Write_Metadata(Item_To_Complete.Source_Directory + "\\marc.xml", Item_To_Complete, options, out Error_Message);

                // Delete the TEMP mets file
                if (File.Exists(userInProcessDirectory + "\\TEMP000001_00001.mets"))
                    File.Delete(userInProcessDirectory + "\\TEMP000001_00001.mets");

                // Rename the METS file to the XML file
                if ((!File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets.xml")) &&
                    (File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets")))
                {
                    File.Move(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets", userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets.xml");
                }

                // Copy this to all the image servers
                SobekCM_Library_Settings.Refresh(Database.SobekCM_Database.Get_Settings_Complete(Tracer));
                string[] allFiles = Directory.GetFiles(userInProcessDirectory);

                string serverNetworkFolder = SobekCM_Library_Settings.Image_Server_Network + Item_To_Complete.Web.AssocFilePath;

                // Create the folder
                if (!Directory.Exists(serverNetworkFolder))
                    Directory.CreateDirectory(serverNetworkFolder);

                foreach (string thisFile in allFiles)
                {
                    string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                    File.Copy(thisFile, destination_file, true);
                }

                // Copy the static HTML file as well
                try
                {
                    if (!Directory.Exists(SobekCM_Library_Settings.Static_Pages_Location + Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8)))
                        Directory.CreateDirectory(SobekCM_Library_Settings.Static_Pages_Location + Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8));
                    if (File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html"))
                        File.Copy(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html", SobekCM_Library_Settings.Static_Pages_Location + Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8) + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html", true);
                }
                catch (Exception)
                {
                    // An error here is not catastrophic
                }

                // Add this to the cache
                itemList.Add_SobekCM_Item(Item_To_Complete);

                // Incrememnt the count of number of items submitted by this user
                user.Items_Submitted_Count++;
                if (!user.BibIDs.Contains(Item_To_Complete.BibID))
                    user.Add_BibID(Item_To_Complete.BibID);

                // Now, delete all the files here
                all_files = Directory.GetFiles(userInProcessDirectory);
                foreach (string thisFile in all_files)
                {
                    File.Delete(thisFile);
                }

                // Finally, set the item for more processing if there were any files
                if (((image_files.Count > 0) || (download_files.Count > 0)) && ( Item_To_Complete.Web.ItemID > 0 ))
                {
                    Database.SobekCM_Database.Update_Additional_Work_Needed_Flag(Item_To_Complete.Web.ItemID, true, Tracer);
                }

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

            }
            catch (Exception ee)
            {
                validationErrors.Add("Error encountered during item save!");
                validationErrors.Add(ee.ToString().Replace("\r", "<br />"));

                // Set an initial flag
                criticalErrorEncountered = true;

                string error_body = "<strong>ERROR ENCOUNTERED DURING ONLINE SUBMITTAL PROCESS</strong><br /><br /><blockquote>Title: " + Item_To_Complete.Bib_Info.Main_Title.Title + "<br />Permanent Link: <a href=\"" + currentMode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "\">" + currentMode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "</a><br />User: "******"<br /><br /></blockquote>" + ee.ToString().Replace("\n", "<br />");
                string error_subject = "Error during submission for '" + Item_To_Complete.Bib_Info.Main_Title.Title + "'";
                string email_to = SobekCM_Library_Settings.System_Error_Email;
                if (email_to.Length == 0)
                    email_to = SobekCM_Library_Settings.System_Email;
                Database.SobekCM_Database.Send_Database_Email(email_to, error_subject, error_body, true, false, -1);
            }

            if (!criticalErrorEncountered)
            {
                // Send email to the email from the template, if one was provided

                if (template.Email_Upon_Receipt.Length > 0)
                {
                    string body = "New item submission complete!<br /><br /><blockquote>Title: " + Item_To_Complete.Bib_Info.Main_Title.Title + "<br />Submittor: " + user.Full_Name + " ( " + user.Email + " )<br />Link: <a href=\"" + currentMode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "\">" + Item_To_Complete.BibID + ":" + Item_To_Complete.VID + "</a></blockquote>";
                    string subject = "Item submission complete for '" + Item_To_Complete.Bib_Info.Main_Title.Title + "'";
                    Database.SobekCM_Database.Send_Database_Email(template.Email_Upon_Receipt, subject, body, true, false, -1);
                }

                // If the user wants to have a message sent, send one
                if (user.Send_Email_On_Submission)
                {
                    // Create the mail message
                    string body2 = "<strong>CONGRATULATIONS!</strong><br /><br />Your item has been successfully added to the digital library and will appear immediately.  Search indexes may take a couple minutes to build, at which time this item will be discoverable through the search interface. <br /><br /><blockquote>Title: " + Item_To_Complete.Bib_Info.Main_Title.Title + "<br />Permanent Link: <a href=\"" + currentMode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "\">" + currentMode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "</a></blockquote>";
                    string subject2 = "Item submission complete for '" + Item_To_Complete.Bib_Info.Main_Title.Title + "'";
                    Database.SobekCM_Database.Send_Database_Email(user.Email, subject2, body2, true, false, -1 );
                }
            }

            return criticalErrorEncountered;
        }
        private bool complete_item_submission(SobekCM_Item Item_To_Complete, Custom_Tracer Tracer)
        {
            // Set an initial flag
            criticalErrorEncountered = false;
            bool xml_found = false;

            // This package is good to go, so build it, save, etc...
            try
            {
                // Save the METS file to the database and back to the directory
                Item_To_Complete.Source_Directory = userInProcessDirectory;

                // Now, add the TEI file
                SobekCM_File_Info tei_newFile = new SobekCM_File_Info(Path.GetFileName(new_tei_file));
                string tei_label = Path.GetFileName(new_tei_file) + " (TEI)";
                Item_To_Complete.Divisions.Download_Tree.Add_File(tei_newFile, tei_label);

                // Save to the database
                try
                {
                    SobekCM_Item_Updater.Update_Item(Item_To_Complete, RequestSpecificValues.Current_User, out error_message);

                    CachedDataManager.Items.Remove_Digital_Resource_Object(RequestSpecificValues.Current_User.UserID, Item_To_Complete.BibID, Item_To_Complete.VID, null);

                    // Also clear the engine
                    SobekEngineClient.Items.Clear_Item_Cache(Item_To_Complete.BibID, Item_To_Complete.VID, RequestSpecificValues.Tracer);
                }
                catch (Exception ee)
                {
                    StreamWriter writer = new StreamWriter(userInProcessDirectory + "\\exception.txt", false);
                    writer.WriteLine("ERROR CAUGHT WHILE SAVING NEW DIGITAL RESOURCE");
                    writer.WriteLine(DateTime.Now.ToString());
                    writer.WriteLine();
                    writer.WriteLine(ee.Message);
                    writer.WriteLine(ee.StackTrace);
                    writer.Flush();
                    writer.Close();
                    throw;
                }

                // Assign the file root and assoc file path
                Item_To_Complete.Web.File_Root = Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8, 2);
                Item_To_Complete.Web.AssocFilePath = Item_To_Complete.Web.File_Root + "\\" + Item_To_Complete.VID + "\\";

                // Save the item settings
                SobekCM_Item_Database.Set_Item_Setting_Value(Item_To_Complete.Web.ItemID, "TEI.Source_File", Path.GetFileName(new_tei_file));
                SobekCM_Item_Database.Set_Item_Setting_Value(Item_To_Complete.Web.ItemID, "TEI.CSS", css_file);
                SobekCM_Item_Database.Set_Item_Setting_Value(Item_To_Complete.Web.ItemID, "TEI.Mapping", mapping_file);

                // Find the actual XSLT file
                string xslt_directory = Path.Combine(UI_ApplicationCache_Gateway.Settings.Servers.Application_Server_Network, "plugins", "tei", "xslt");
                string[] xslt_files = Directory.GetFiles(xslt_directory, xslt_file + ".xsl*");
                SobekCM_Item_Database.Set_Item_Setting_Value(Item_To_Complete.Web.ItemID, "TEI.XSLT", Path.GetFileName(xslt_files[0]));

                // Add the TEI viewer
                SobekCM_Item_Database.Save_Item_Add_Viewer(Item_To_Complete.Web.ItemID, "TEI", new_tei_file.Replace(".xml", "").Replace(".XML", "") + " (TEI)", new_tei_file);

                // Create the static html pages
                string base_url = RequestSpecificValues.Current_Mode.Base_URL;
                try
                {
                    Static_Pages_Builder staticBuilder = new Static_Pages_Builder(UI_ApplicationCache_Gateway.Settings.Servers.System_Base_URL, UI_ApplicationCache_Gateway.Settings.Servers.Base_Data_Directory, RequestSpecificValues.HTML_Skin.Skin_Code);
                    string filename = userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html";
                    staticBuilder.Create_Item_Citation_HTML(Item_To_Complete, filename, String.Empty);

                    // Copy the static HTML file to the web server
                    try
                    {
                        if (!Directory.Exists(UI_ApplicationCache_Gateway.Settings.Servers.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8)))
                            Directory.CreateDirectory(UI_ApplicationCache_Gateway.Settings.Servers.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8));
                        if (File.Exists(userInProcessDirectory + "\\" + item.BibID + "_" + item.VID + ".html"))
                            File.Copy(userInProcessDirectory + "\\" + item.BibID + "_" + item.VID + ".html", UI_ApplicationCache_Gateway.Settings.Servers.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8) + "\\" + item.BibID + "_" + item.VID + ".html", true);
                    }
                    catch (Exception)
                    {
                        // This is not critical
                    }
                }
                catch (Exception)
                {
                    // An error here is not catastrophic
                }

                RequestSpecificValues.Current_Mode.Base_URL = base_url;

                // Save the rest of the metadata
                Item_To_Complete.Save_SobekCM_METS();

                // Create the options dictionary used when saving information to the database, or writing MarcXML
                Dictionary<string, object> options = new Dictionary<string, object>();
                if (UI_ApplicationCache_Gateway.Settings.MarcGeneration != null)
                {
                    options["MarcXML_File_ReaderWriter:MARC Cataloging Source Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Cataloging_Source_Code;
                    options["MarcXML_File_ReaderWriter:MARC Location Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Location_Code;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Agency"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Agency;
                    options["MarcXML_File_ReaderWriter:MARC Reproduction Place"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Place;
                    options["MarcXML_File_ReaderWriter:MARC XSLT File"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.XSLT_File;
                }
                options["MarcXML_File_ReaderWriter:System Name"] = UI_ApplicationCache_Gateway.Settings.System.System_Name;
                options["MarcXML_File_ReaderWriter:System Abbreviation"] = UI_ApplicationCache_Gateway.Settings.System.System_Abbreviation;

                // Save the marc xml file
                MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
                string errorMessage;
                marcWriter.Write_Metadata(Item_To_Complete.Source_Directory + "\\marc.xml", Item_To_Complete, options, out errorMessage);

                // Delete the TEMP mets file
                if (File.Exists(userInProcessDirectory + "\\TEMP000001_00001.mets"))
                    File.Delete(userInProcessDirectory + "\\TEMP000001_00001.mets");

                // Rename the METS file to the XML file
                if ((!File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets.xml")) &&
                    (File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets")))
                {
                    File.Move(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets", userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".mets.xml");
                }

                string serverNetworkFolder = UI_ApplicationCache_Gateway.Settings.Servers.Image_Server_Network + Item_To_Complete.Web.AssocFilePath;

                // Create the folder
                if (!Directory.Exists(serverNetworkFolder))
                    Directory.CreateDirectory(serverNetworkFolder);
                if (!Directory.Exists(serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name))
                    Directory.CreateDirectory(serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name);

                // Copy the static HTML page over first
                if (File.Exists(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html"))
                {
                    File.Copy(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html", serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name + "\\" + item.BibID + "_" + item.VID + ".html", true);
                    File.Delete(userInProcessDirectory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html");
                }

                // Copy all the files
                string[] allFiles = Directory.GetFiles(userInProcessDirectory);
                foreach (string thisFile in allFiles)
                {
                    string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                    File.Copy(thisFile, destination_file, true);
                }

                // Add this to the cache
                UI_ApplicationCache_Gateway.Items.Add_SobekCM_Item(Item_To_Complete);

                // Now, delete all the files here
                string[] all_files = Directory.GetFiles(userInProcessDirectory);
                foreach (string thisFile in all_files)
                {
                    File.Delete(thisFile);
                }

                // Always set the additional work needed flag, to give the builder a  chance to look at it
                SobekCM_Database.Update_Additional_Work_Needed_Flag(Item_To_Complete.Web.ItemID, true, Tracer);

            }
            catch (Exception ee)
            {
                validationErrors.Add("Error encountered during item save!");
                validationErrors.Add(ee.ToString().Replace("\r", "<br />"));

                // Set an initial flag
                criticalErrorEncountered = true;

                string error_body = "<strong>ERROR ENCOUNTERED DURING ONLINE SUBMITTAL PROCESS</strong><br /><br /><blockquote>Title: " + Item_To_Complete.Bib_Info.Main_Title.Title + "<br />Permanent Link: <a href=\"" + RequestSpecificValues.Current_Mode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "\">" + RequestSpecificValues.Current_Mode.Base_URL + "/" + Item_To_Complete.BibID + "/" + Item_To_Complete.VID + "</a><br />User: "******"<br /><br /></blockquote>" + ee.ToString().Replace("\n", "<br />");
                string error_subject = "Error during submission for '" + Item_To_Complete.Bib_Info.Main_Title.Title + "'";
                string email_to = UI_ApplicationCache_Gateway.Settings.Email.System_Error_Email;
                if (email_to.Length == 0)
                    email_to = UI_ApplicationCache_Gateway.Settings.Email.System_Email;
                Email_Helper.SendEmail(email_to, error_subject, error_body, true, RequestSpecificValues.Current_Mode.Instance_Name);
            }

            // Also clear some values from the session
            HttpContext.Current.Session["Edit_TEI_Item_MySobekViewer." + bibid + "_" + vid + ".Mapping_File"] = null;
            HttpContext.Current.Session["Edit_TEI_Item_MySobekViewer." + bibid + "_" + vid + ".XSLT_File"] = null;
            HttpContext.Current.Session["Edit_TEI_Item_MySobekViewer." + bibid + "_" + vid + ".CSS_File"] = null;
            HttpContext.Current.Session["Edit_TEI_Item_MySobekViewer." + bibid + "_" + vid + ".Original_TEI_File"] = null;
            HttpContext.Current.Session["Edit_TEI_mySobekViewer." + bibid + "_" + vid + ".New_Item"] = null;

            if (!criticalErrorEncountered)
            {
                // Also clear any searches or browses ( in the future could refine this to only remove those
                // that are impacted by this save... but this is good enough for now )
                CachedDataManager.Clear_Search_Results_Browses();

                // Redirect to the item page
                RequestSpecificValues.Current_Mode.Mode = Display_Mode_Enum.Item_Display;
                RequestSpecificValues.Current_Mode.BibID = bibid;
                RequestSpecificValues.Current_Mode.VID = vid;
                UrlWriterHelper.Redirect(RequestSpecificValues.Current_Mode);
            }

            return criticalErrorEncountered;
        }
        private void complete_item_submission(SobekCM_Item Item_To_Complete, Custom_Tracer Tracer)
        {
            // If this is a newspaper type, and the pubdate has a value, try to use that for the serial heirarchy
            if ((Item_To_Complete.Behaviors.Serial_Info.Count == 0) && (Item_To_Complete.Bib_Info.Origin_Info.Date_Issued.Length > 0) && (Item_To_Complete.Bib_Info.SobekCM_Type == TypeOfResource_SobekCM_Enum.Newspaper ))
            {
                    DateTime asDateTime;
                    if (DateTime.TryParse(Item_To_Complete.Bib_Info.Origin_Info.Date_Issued, out asDateTime))
                    {
                        hierarchyCopiedFromDate = true;
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(1, asDateTime.Year, asDateTime.Year.ToString());
                        switch (asDateTime.Month)
                        {
                            case 1:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "January");
                                break;

                            case 2:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "February");
                                break;

                            case 3:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "March");
                                break;

                            case 4:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "April");
                                break;

                            case 5:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "May");
                                break;

                            case 6:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "June");
                                break;

                            case 7:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "July");
                                break;

                            case 8:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "August");
                                break;

                            case 9:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "September");
                                break;

                            case 10:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "October");
                                break;

                            case 11:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "November");
                                break;

                            case 12:
                                Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "December");
                                break;
                        }

                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(3, asDateTime.Day, asDateTime.Day.ToString());
                    }
            }

            // Determine the in process directory for this
            string user_in_process_directory = UI_ApplicationCache_Gateway.Settings.Servers.In_Process_Submission_Location + "\\" + RequestSpecificValues.Current_User.UserName.Replace(".", "").Replace("@", "") + "\\newitem";
            if (RequestSpecificValues.Current_User.ShibbID.Trim().Length > 0)
                user_in_process_directory = UI_ApplicationCache_Gateway.Settings.Servers.In_Process_Submission_Location + "\\" + RequestSpecificValues.Current_User.ShibbID + "\\newitem";

            // Ensure this directory exists
            if (!Directory.Exists(user_in_process_directory))
                Directory.CreateDirectory(user_in_process_directory);

            // Now, delete all the files in the processing directory
            string[] all_files = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in all_files)
            {
                File.Delete(thisFile);
            }

            // Save to the database
            Item_To_Complete.Web.File_Root = Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8, 2);
            SobekCM_Item_Database.Save_New_Digital_Resource(Item_To_Complete, false, false, RequestSpecificValues.Current_User.UserName, String.Empty, -1);

            // Assign the file root and assoc file path
            Item_To_Complete.Web.AssocFilePath = Item_To_Complete.Web.File_Root + "\\" + Item_To_Complete.VID + "\\";

            // Create the static html pages
            string base_url = RequestSpecificValues.Current_Mode.Base_URL;

            // Save the rest of the metadata
            Item_To_Complete.Source_Directory = user_in_process_directory;
            Item_To_Complete.Save_SobekCM_METS();

            // Add this to the cache
            UI_ApplicationCache_Gateway.Items.Add_SobekCM_Item(Item_To_Complete);

            Database.SobekCM_Database.Add_Item_To_User_Folder(RequestSpecificValues.Current_User.UserID, "Submitted Items", Item_To_Complete.BibID, Item_To_Complete.VID, 0, String.Empty, Tracer);

            // Save Bib_Level METS?
            //SobekCM.Resource_Object.Writers.OAI_Writer oaiWriter = new SobekCM.Resource_Object.Writers.OAI_Writer();
            //oaiWriter.Save_OAI_File(bibPackage, resource_folder + "\\oai_dc.xml", bibPackage.Processing_Parameters.Collection_Primary.ToLower(), createDate);

            // If there was no match, try to save to the tracking database
            Engine_Database.Tracking_Online_Submit_Complete(Item_To_Complete.Web.ItemID, RequestSpecificValues.Current_User.Full_Name, String.Empty);

            // Create the options dictionary used when saving information to the database, or writing MarcXML
            Dictionary<string, object> options = new Dictionary<string, object>();
            if (UI_ApplicationCache_Gateway.Settings.MarcGeneration != null)
            {
                options["MarcXML_File_ReaderWriter:MARC Cataloging Source Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Cataloging_Source_Code;
                options["MarcXML_File_ReaderWriter:MARC Location Code"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Location_Code;
                options["MarcXML_File_ReaderWriter:MARC Reproduction Agency"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Agency;
                options["MarcXML_File_ReaderWriter:MARC Reproduction Place"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.Reproduction_Place;
                options["MarcXML_File_ReaderWriter:MARC XSLT File"] = UI_ApplicationCache_Gateway.Settings.MarcGeneration.XSLT_File;
            }
            options["MarcXML_File_ReaderWriter:System Name"] = UI_ApplicationCache_Gateway.Settings.System.System_Name;
            options["MarcXML_File_ReaderWriter:System Abbreviation"] = UI_ApplicationCache_Gateway.Settings.System.System_Abbreviation;

            // Save the MARC file
            MarcXML_File_ReaderWriter marcWriter = new MarcXML_File_ReaderWriter();
            string errorMessage;
            marcWriter.Write_Metadata(Item_To_Complete.Source_Directory + "\\marc.xml", Item_To_Complete, options, out errorMessage);

            // Copy all the files over to the server
            string serverNetworkFolder = UI_ApplicationCache_Gateway.Settings.Servers.Image_Server_Network + Item_To_Complete.Web.AssocFilePath;

            // Create the folder
            if (!Directory.Exists(serverNetworkFolder))
                Directory.CreateDirectory(serverNetworkFolder);
            if (!Directory.Exists(serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name))
                Directory.CreateDirectory(serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name);

            // Copy the static HTML page over first
            if (File.Exists(user_in_process_directory + "\\" + currentItem.BibID + "_" + currentItem.VID + ".html"))
            {
                File.Copy(user_in_process_directory + "\\" + currentItem.BibID + "_" + currentItem.VID + ".html", serverNetworkFolder + "\\" + UI_ApplicationCache_Gateway.Settings.Resources.Backup_Files_Folder_Name + "\\" + currentItem.BibID + "_" + currentItem.VID + ".html", true);
                File.Delete(user_in_process_directory + "\\" + currentItem.BibID + "_" + currentItem.VID + ".html");
            }

            // Copy all the files
            string[] allFiles = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in allFiles)
            {
                string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                File.Copy(thisFile, destination_file, true);
            }

            // Add this to the cache
            UI_ApplicationCache_Gateway.Items.Add_SobekCM_Item(Item_To_Complete);

            // Incrememnt the count of number of items submitted by this user
            RequestSpecificValues.Current_User.Items_Submitted_Count++;

            // Delete any remaining items
            all_files = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in all_files)
            {
                File.Delete(thisFile);
            }
        }