public SobekCM_Page_Globals(bool isPostBack, string page_name)
        {
            // Pull out the http request
            HttpRequest request = HttpContext.Current.Request;

            // Get the base url
            string base_url = request.Url.AbsoluteUri.ToLower().Replace("sobekcm.aspx", "");
            if (base_url.IndexOf("?") > 0)
                base_url = base_url.Substring(0, base_url.IndexOf("?"));

            try
            {
                tracer = new Custom_Tracer();
                tracer.Add_Trace("SobekCM_Page_Globals.Constructor", String.Empty);

                // Don't really need to *build* these, so just define them as a new ones if null
                if (Global.Checked_List == null)
                    Global.Checked_List = new Checked_Out_Items_List();
                if (Global.Search_History == null)
                    Global.Search_History = new Recent_Searches();

                // Make sure all the needed data is loaded into the Application State
                Application_State_Builder.Build_Application_State(tracer, false, ref Global.Skins, ref Global.Translation,
                                                                  ref Global.Codes, ref Global.Item_List, ref Global.Icon_List,
                                                                  ref Global.Stats_Date_Range, ref Global.Thematic_Headings, ref Global.Collection_Aliases, ref Global.IP_Restrictions,
                                                                  ref Global.URL_Portals, ref Global.Mime_Types, ref Global.Item_Viewer_Priority);

                tracer.Add_Trace("SobekCM_Page_Globals.Constructor", "Application State validated or built");

                // Check that something is saved for the original requested URL (may not exist if not forwarded)
                if (!HttpContext.Current.Items.Contains("Original_URL"))
                    HttpContext.Current.Items["Original_URL"] = request.Url.ToString();
            }
            catch (Exception ee)
            {
                // Send to the dashboard
                if ((HttpContext.Current.Request.UserHostAddress == "127.0.0.1") || (HttpContext.Current.Request.UserHostAddress == HttpContext.Current.Request.ServerVariables["LOCAL_ADDR"]) || (HttpContext.Current.Request.Url.ToString().IndexOf("localhost") >= 0))
                {
                    // Create an error message
                    string errorMessage = "Error caught while validating application state";
                    if ((SobekCM_Library_Settings.Database_Connections.Count == 0) || (String.IsNullOrEmpty(SobekCM_Library_Settings.Database_Connections[0].Connection_String)))
                    {
                        errorMessage = "No database connection string found!";
                        string configFileLocation = AppDomain.CurrentDomain.BaseDirectory + "config/sobekcm.xml";
                        try
                        {
                            if (!File.Exists(configFileLocation))
                            {
                                errorMessage = "Missing config/sobekcm.xml configuration file on the web server.<br />Ensure the configuration file 'sobekcm.xml' exists in a 'config' subfolder directly under the web application.<br />Example configuration is:" +
                                               "<div style=\"background-color: #bbbbbb; margin-left: 30px; margin-top:10px; padding: 3px;\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;  ?&gt;<br /> &lt;configuration&gt;<br /> &nbsp; &nbsp &lt;connection_string type=&quot;MSSQL&quot;&gt;data source=localhost\\instance;initial catalog=SobekCM;integrated security=Yes;&lt;/connection_string&gt;<br /> &nbsp; &nbsp &lt;error_emails&gt;[email protected]&lt;/error_emails&gt;<br /> &nbsp; &nbsp &lt;error_page&gt;http://ufdc.ufl.edu/error.html&lt;/error_page&gt;<br />&lt;/configuration&gt;</div>";
                            }
                        }
                        catch
                        {
                            errorMessage = "No database connection string found.<br />Likely an error reading the configuration file due to permissions on the web server.<br />Ensure the configuration file 'sobekcm.xml' exists in a 'config' subfolder directly under the web application.<br />Example configuration is:" +
                                           "<div style=\"background-color: #bbbbbb; margin-left: 30px; margin-top:10px; padding: 3px;\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;  ?&gt;<br /> &lt;configuration&gt;<br /> &nbsp; &nbsp &lt;connection_string type=&quot;MSSQL&quot;&gt;data source=localhost\\instance;initial catalog=SobekCM;integrated security=Yes;&lt;/connection_string&gt;<br /> &nbsp; &nbsp &lt;error_emails&gt;[email protected]&lt;/error_emails&gt;<br /> &nbsp; &nbsp &lt;error_page&gt;http://ufdc.ufl.edu/error.html&lt;/error_page&gt;<br />&lt;/configuration&gt;</div>";
                        }
                    }
                    else
                    {
                        if (ee.Message.IndexOf("The EXECUTE permission") >= 0)
                        {
                            errorMessage = "Permissions error while connecting to the database and pulling necessary data.<br /><br />Confirm the following:<ul><li>IIS is configured correctly to use anonymous authentication</li><li>Anonymous user (or service account) is part of the sobek_users role in the database.</li></ul>";
                        }
                        else
                        {
                            errorMessage = "Error connecting to the database and pulling necessary data.<br /><br />Confirm the following:<ul><li>Database connection string is correct ( " + SobekCM_Library_Settings.Database_Connections[0].Connection_String + ")</li><li>IIS is configured correctly to use anonymous authentication</li><li>Anonymous user (or service account) is part of the sobek_users role in the database.</li></ul>";
                        }
                    }
                    // Wrap this into the SobekCM Exception
                    SobekCM_Traced_Exception newException = new SobekCM_Traced_Exception(errorMessage, ee, tracer);

                    // Save this to the session state, and then forward to the dashboard
                    HttpContext.Current.Session["Last_Exception"] = newException;
                    HttpContext.Current.Response.Redirect("dashboard.aspx", false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    return;
                }
                else
                {
                    throw ee;
                }
            }

            // Analyze the response and get the mode
            try
            {
                currentMode = new SobekCM_Navigation_Object(request.QueryString, base_url, request.UserLanguages, Global.Codes, Global.Collection_Aliases, ref Global.Item_List, Global.URL_Portals, tracer)
                    {
                        Base_URL = base_url,
                        isPostBack = isPostBack,
                        Browser_Type = request.Browser.Type.ToUpper()
                    };
                currentMode.Set_Robot_Flag(request.UserAgent, request.UserHostAddress);
            }
            catch
            {
                HttpContext.Current.Response.Status = "301 Moved Permanently";
                HttpContext.Current.Response.AddHeader("Location", base_url);
                HttpContext.Current.ApplicationInstance.CompleteRequest();
                return;
            }

            // If this was for HTML, but was at the data, just convert to XML
            if ((page_name == "SOBEKCM_DATA") && (currentMode.Writer_Type != Writer_Type_Enum.XML) && (currentMode.Writer_Type != Writer_Type_Enum.JSON) && (currentMode.Writer_Type != Writer_Type_Enum.DataSet) && (currentMode.Writer_Type != Writer_Type_Enum.Data_Provider))
                currentMode.Writer_Type = Writer_Type_Enum.XML;

            tracer.Add_Trace("SobekCM_Page_Globals.Constructor", "Navigation Object created from URI query string");

            // Need to ensure the list of items was pulled for several modes
            if (((currentMode.Writer_Type != Writer_Type_Enum.HTML) && (currentMode.Writer_Type != Writer_Type_Enum.HTML_Echo) && (currentMode.Writer_Type != Writer_Type_Enum.HTML_LoggedIn)) ||
                (currentMode.Mode == Display_Mode_Enum.Item_Display) ||
                (currentMode.Mode == Display_Mode_Enum.Item_Print) ||
                (currentMode.Mode == Display_Mode_Enum.Results) ||
                ((currentMode.Mode == Display_Mode_Enum.Aggregation) && ((currentMode.Aggregation_Type == Aggregation_Type_Enum.Browse_Info) || (currentMode.Aggregation_Type == Aggregation_Type_Enum.Child_Page_Edit) || (currentMode.Aggregation_Type == Aggregation_Type_Enum.Browse_Map))) ||
                (currentMode.Mode == Display_Mode_Enum.Public_Folder) ||
                ((currentMode.Mode == Display_Mode_Enum.My_Sobek) && ((currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Delete_Item) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Edit_Group_Behaviors) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Edit_Group_Serial_Hierarchy) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Edit_Item_Metadata) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.File_Management) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Folder_Management) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Group_Add_Volume) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Group_AutoFill_Volumes) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Group_Mass_Update_Items) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.New_Item) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Page_Images_Management))))
            {
                SobekCM_Database.Verify_Item_Lookup_Object(true, ref Global.Item_List, tracer);
            }

            try
            {
                if (currentMode.Aggregation.ToUpper() == "EPCSANB")
                {
                    HttpContext.Current.Response.Redirect(@"http://www.uflib.ufl.edu/epc/", false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    currentMode.Request_Completed = true;
                    return;
                }

                // If this was an error, redirect now
                if (currentMode.Mode == Display_Mode_Enum.Error)
                {
                    return;
                }

                // All the user stuff can be skipped if this was from a robot
                if (!currentMode.Is_Robot)
                {
                    // Determine which IP Ranges this IP address belongs to, if not already determined.
                    if (HttpContext.Current.Session["IP_Range_Membership"] == null)
                    {
                        int ip_mask = Global.IP_Restrictions.Restrictive_Range_Membership(request.UserHostAddress);
                        HttpContext.Current.Session["IP_Range_Membership"] = ip_mask;
                    }

                    // Set the Session TOC, if provided
                    if (currentMode.TOC_Display != TOC_Display_Type_Enum.Undetermined)
                    {
                        if (currentMode.TOC_Display == TOC_Display_Type_Enum.Hide)
                        {
                            HttpContext.Current.Session["Show TOC"] = false;
                        }
                        else
                        {
                            HttpContext.Current.Session["Show TOC"] = true;
                        }
                    }

                    // Only do any of the user stuff if this is from the main SobekCM page
                    if (page_name == "SOBEKCM")
                    {
                        tracer.Add_Trace("SobekCM_Page_Globals.Constructor", "Checking for logged on user by cookie or session");
                        perform_user_checks(isPostBack);
                    }

                    // If this is a system admin, they can run as a different user actually
                    if ((currentUser != null) && (currentUser.Is_System_Admin) && (request.QueryString["userid"] != null))
                    {
                        try
                        {
                            int userid = Convert.ToInt32(request.QueryString["userid"]);
                            User_Object mirroredUser = SobekCM_Database.Get_User(userid, tracer);
                            if (mirroredUser != null)
                            {
                                // Replace the user information in the session state
                                HttpContext.Current.Session["user"] = mirroredUser;
                                currentUser = mirroredUser;
                            }
                        }
                        catch (Exception)
                        {
                            // Nothing to do here.. shouldn't ever really be here..
                        }
                    }

                    if (currentMode.Request_Completed)
                        return;

                    // If this was a call for RESET, clear the memory
                    if ((currentMode.Mode == Display_Mode_Enum.Administrative) && (currentMode.Admin_Type == Admin_Type_Enum.Reset))
                    {
                        Reset_Memory();

                        // Since this reset, send to the admin, memory management portion
                        currentMode.Mode = Display_Mode_Enum.Internal;
                        currentMode.Internal_Type = Internal_Type_Enum.Cache;
                    }
                }
                else // THIS IS A ROBOT REQUEST
                {
                    Perform_Search_Engine_Robot_Checks(currentMode, request.QueryString);
                }

                // If this is for a public folder, get the data
                if (currentMode.Mode == Display_Mode_Enum.Public_Folder)
                {
                    Public_Folder();
                }

                // Get the item now, so that you can set the collection code, if there was none listed
                if ((currentMode.Mode == Display_Mode_Enum.Item_Display) || (currentMode.Mode == Display_Mode_Enum.Item_Print) || ((currentMode.Mode == Display_Mode_Enum.My_Sobek) && ((currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Edit_Item_Metadata) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Edit_Item_Behaviors)))
                    || ((currentMode.Mode == Display_Mode_Enum.My_Sobek) && ((currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Edit_Group_Behaviors) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Edit_Group_Serial_Hierarchy) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Group_Add_Volume) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Group_AutoFill_Volumes) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Group_Mass_Update_Items) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.File_Management) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Page_Images_Management) || (currentMode.My_Sobek_Type == My_Sobek_Type_Enum.Delete_Item))))
                {
                    Display_Item();
                }

                // Was this a robot?
                if (currentMode.Request_Completed)
                    return;

                // Get the group, collection, or subcollection from the database or cache.
                // This also makes sure they are a proper hierarchy.
                Get_Entire_Collection_Hierarchy();

                // Run the search if this should be done now
                if (currentMode.Mode == Display_Mode_Enum.Results)
                {
                    Search_Block();
                }

                // Run the browse/info work if it is of those modes
                if ((currentMode.Mode == Display_Mode_Enum.Aggregation) && ((currentMode.Aggregation_Type == Aggregation_Type_Enum.Browse_Info) || (currentMode.Aggregation_Type == Aggregation_Type_Enum.Child_Page_Edit)))
                {
                    Browse_Info_Block();
                }

                if (currentMode.Mode == Display_Mode_Enum.My_Sobek)
                {
                    MySobekCM_Block();
                }

                // Run the simple text block if this is that mode
                if (currentMode.Mode == Display_Mode_Enum.Simple_HTML_CMS)
                {
                    Simple_Web_Content_Text_Block();
                }
            }
            catch (OutOfMemoryException ee)
            {
                if (currentMode != null)
                {
                    currentMode.Mode = Display_Mode_Enum.Error;
                    currentMode.Error_Message = "Out of memory exception caught";
                    currentMode.Caught_Exception = ee;
                }
                else
                {
                    Email_Information("Fatal Out of memory exception caught", ee);
                }
            }
            catch (Exception ee)
            {
                if (currentMode != null)
                {
                    currentMode.Mode = Display_Mode_Enum.Error;
                    currentMode.Error_Message = "Unknown error occurred";
                    currentMode.Caught_Exception = ee;
                }
                else
                {
                    Email_Information("Unknown Fatal Error Occurred", ee);
                }
            }
        }
        /// <summary> Read a IIS web log, analyze completely, and return the corresponding <see cref="SobekCM_Stats_DataSet"/> object </summary>
        /// <param name="Log_File"> Location for the log file to read </param>
        /// <returns> Object with all the analyzed hits and sessions from the web log </returns>
        public SobekCM_Stats_DataSet Read_Log(string Log_File)
        {
            // Get list of ips which include dloc.com
            dloc_ips = new List<string>();

            // Create the list of hits
            hits = new SortedList<SobekCM_Hit, SobekCM_Hit>();

            // Create the list of sessions
            sessions = new Dictionary<string, SobekCM_Session>();

            // Create the return set
            SobekCM_Stats_DataSet returnValue = new SobekCM_Stats_DataSet();

            // Get the date of the log file
            FileInfo fileInfo = new FileInfo(Log_File);
            string name = fileInfo.Name.Replace(fileInfo.Extension, "");
            DateTime logDate = new DateTime(Convert.ToInt32("20" + name.Substring(4, 2)),
                                            Convert.ToInt32(name.Substring(6, 2)), Convert.ToInt32(name.Substring(8, 2)));
            returnValue.Date = logDate;

            // Open a connection to the log file and save each hit
            StreamReader reader = new StreamReader(Log_File);
            string line = reader.ReadLine();
            while (line != null)
            {
                parse_line(line);
                line = reader.ReadLine();
            }

            // Now, step through each hit in the list
            foreach (SobekCM_Hit hit in hits.Values)
            {
                if (hit.UFDC_URL.ToUpper().IndexOf(".ASPX") < 0)
                {
                    // Always increment the hits
                    returnValue.Increment_Hits();

                    // Add this IP hit
                    returnValue.Add_IP_Hit(hit.IP, hit.UserAgent);

                    // Shouldn't start with '/'
                    if (hit.UFDC_URL[0] == '/')
                    {
                        hit.UFDC_URL = hit.UFDC_URL.Substring(1);
                    }
                    hit.UFDC_URL = hit.UFDC_URL.ToLower();
                    if (hit.UFDC_URL.IndexOf("design/webcontent/") == 0)
                        hit.UFDC_URL = hit.UFDC_URL.Substring(18);

                    // Add this as a webcontent hit
                    returnValue.Add_WebContent_Hit(hit.UFDC_URL);
                }
                else
                {
                    // parse the url
                    string[] splitter = hit.Query_String.ToLower().Split("&".ToCharArray());
                    NameValueCollection queryStringCollection = new NameValueCollection();
                    foreach (string thisSplit in splitter)
                    {
                        int equals_index = thisSplit.IndexOf("=");
                        if ((equals_index > 0) && (equals_index < thisSplit.Length - 1))
                        {
                            string query_name = thisSplit.Substring(0, equals_index);
                            string query_value = thisSplit.Substring(equals_index + 1);
                            queryStringCollection[query_name] = query_value;

                            if (query_name.ToLower() == "portal")
                                hit.UFDC_URL = query_value;
                        }
                    }

                    // Now, get the navigation object using the standard SobekCM method

                    try
                    {
                        SobekCM_Navigation_Object currentMode = new SobekCM_Navigation_Object(queryStringCollection, hit.UFDC_URL,
                                                                                              new string[] {"en"}, Codes, Collection_Aliases,
                                                                                              ref Item_Lookup_Object, URL_Portals, null);
                        if (currentMode != null)
                            currentMode.Set_Robot_Flag(hit.UserAgent, hit.IP);
                        if ((currentMode != null) && (!currentMode.Is_Robot))
                        {
                            // Always increment the hits
                            returnValue.Increment_Hits();

                            // Add this IP hit
                            returnValue.Add_IP_Hit(hit.IP, hit.UserAgent);

                            // Increment the portal hits
                            returnValue.Add_Portal_Hit(currentMode.SobekCM_Instance_Name.ToUpper());

                            // Check for pre-existing session
                            SobekCM_Session thisSession;
                            if (sessions.ContainsKey(hit.IP))
                            {
                                SobekCM_Session possibleSession = sessions[hit.IP];
                                TimeSpan difference = hit.Time.Subtract(possibleSession.Last_Hit);
                                if (difference.TotalMinutes >= 60)
                                {
                                    thisSession = new SobekCM_Session(hit.IP, hit.Time);
                                    sessions[hit.IP] = thisSession;

                                    returnValue.Increment_Sessions();
                                }
                                else
                                {
                                    possibleSession.Last_Hit = hit.Time;
                                    thisSession = possibleSession;
                                }
                            }
                            else
                            {
                                thisSession = new SobekCM_Session(hit.IP, hit.Time);
                                sessions.Add(hit.IP, thisSession);

                                returnValue.Increment_Sessions();
                            }

                            if ((currentMode.Mode == Display_Mode_Enum.Item_Display) ||
                                (currentMode.Mode == Display_Mode_Enum.Item_Print))
                            {
                                if ((currentMode.ItemID_DEPRECATED > 0) ||
                                    ((currentMode.VID.Length > 0) && (currentMode.BibID.Length > 0)))
                                {
                                    if (currentMode.ItemID_DEPRECATED <= 0)
                                    {
                                        DataRow[] ufdc2_bib_select =
                                            itemList.Select("bibid = '" + currentMode.BibID + "' and vid='" +
                                                            currentMode.VID + "'");
                                        if (ufdc2_bib_select.Length > 0)
                                        {
                                            currentMode.ItemID_DEPRECATED =
                                                Convert.ToInt32(ufdc2_bib_select[0]["itemid"]);
                                        }
                                    }

                                    returnValue.Add_Item_Hit(currentMode.ItemID_DEPRECATED, currentMode.BibID,
                                                             currentMode.VID, currentMode.ViewerCode.ToUpper(),
                                                             currentMode.Text_Search, thisSession.SessionID);
                                }
                                else if (currentMode.BibID.Length > 0)
                                {
                                    returnValue.Add_Bib_Hit(currentMode.BibID.ToUpper(), thisSession.SessionID);
                                }
                            }
                            else
                            {
                                string code = currentMode.Aggregation;
                                string institution = String.Empty;
                                if ((code.Length > 0) && (code.ToUpper()[0] == 'I'))
                                {
                                    institution = code;
                                    code = String.Empty;
                                }

                                if ((institution.Length > 0) && (institution.ToUpper()[0] != 'I'))
                                    institution = "i" + institution;

                                // For some collections we are counting the institution hit and collection
                                // hit just so the full use of the site is recorded
                                if (code.Length > 0)
                                {
                                    returnValue.Add_Collection_Hit(code.ToLower(), currentMode.Mode,
                                                                   thisSession.SessionID);
                                }

                                // Was this an institutional level hit?
                                if (institution.Length > 0)
                                {
                                    returnValue.Add_Institution_Hit(institution.ToLower(), currentMode.Mode,
                                                                    thisSession.SessionID);
                                }

                                // Is this a static "webcontent" top-level page?
                                if (currentMode.Mode == Display_Mode_Enum.Simple_HTML_CMS)
                                {
                                    if ((currentMode.Info_Browse_Mode != "unknown") &&
                                        (currentMode.Info_Browse_Mode != "default"))
                                    {
                                        returnValue.Add_WebContent_Hit(currentMode.Info_Browse_Mode.ToLower());
                                    }
                                }

                                // Add the write type, if not normal HTML stuff
                                switch (currentMode.Writer_Type)
                                {
                                    case Writer_Type_Enum.DataSet:
                                    case Writer_Type_Enum.XML:
                                        returnValue.Add_XML_Hit();
                                        break;

                                    case Writer_Type_Enum.OAI:
                                        returnValue.Add_OAI_Hit();
                                        break;

                                    case Writer_Type_Enum.JSON:
                                        returnValue.Add_JSON_Hit();
                                        break;
                                }
                            }
                        }
                        else
                        {
                            if ((currentMode != null) && (currentMode.Is_Robot))
                                returnValue.Add_Robot_Hit();
                        }
                    }
                    catch (Exception ee)
                    {
                        bool error = true;
                    }

                    //System.Windows.Forms.MessageBox.Show("'" + hit.Time.ToString() + "' '" + hit.IP + "' '" + hit.UFDC_URL + "'");
                }
            }

            return returnValue;
        }