private void process_bib_desc(XmlNodeReader nodeReader, SobekCM_Item thisPackage)
        {
            // Set some counters for the creator role/date and contributor role/date
            int creatorRole = 0;
            int creatorDate = 0;
            //int contribRole = 0;
            //int contribDate = 0;

            // Read all the nodes
            while (nodeReader.Read())
            {
                // If this is the end tag for bibDesc, return
                if ((nodeReader.NodeType == XmlNodeType.EndElement) && (nodeReader.Name.Trim().ToUpper() == "BIBDESC"))
                {
                    return;
                }

                // If this is the beginning tag for an element, assign the next values accordingly
                if (nodeReader.NodeType == XmlNodeType.Element)
                {
                    // Switch based on the element name
                    switch (nodeReader.Name.Trim().ToUpper())
                    {
                        case "DC.TITLE":
                            thisPackage.Bib_Info.Main_Title.Title = read_text_node(nodeReader);
                            break;
                        case "DC.RIGHTS":
                            thisPackage.Bib_Info.Access_Condition.Text = read_text_node(nodeReader);
                            break;
                        case "DC.IDENTIFIER":
                            thisPackage.Bib_Info.Add_Identifier(read_text_node(nodeReader));
                            break;
                        case "DC.DATE":
                            thisPackage.Bib_Info.Origin_Info.Date_Issued = read_text_node(nodeReader);
                            break;
                        case "DC.CREATOR":
                            thisPackage.Bib_Info.Add_Named_Entity(read_text_node(nodeReader), "creator");
                            break;
                        case "PALMM.CREATORROLE":
                            if (thisPackage.Bib_Info.Names_Count > creatorRole)
                            {
                                if (thisPackage.Bib_Info.Names[creatorRole].Roles.Count == 0)
                                {
                                    thisPackage.Bib_Info.Names[creatorRole].Roles.Add(new Name_Info_Role(read_text_node(nodeReader), Name_Info_Role_Type_Enum.text));
                                }
                                else
                                {
                                    thisPackage.Bib_Info.Names[creatorRole].Roles[0].Role = read_text_node(nodeReader);
                                }
                                creatorRole++;
                            }
                            break;
                        case "PALMM.CREATORDATES":
                            if (thisPackage.Bib_Info.Names_Count > creatorDate)
                            {
                                thisPackage.Bib_Info.Names[creatorDate++].Dates = read_text_node(nodeReader);
                            }
                            break;
                        case "DC.CONTRIBUTOR":
                            thisPackage.Bib_Info.Add_Named_Entity(new Name_Info(read_text_node(nodeReader), "contributor"));
                            break;
                        case "DC.DESCRIPTION":
                            thisPackage.Bib_Info.Add_Note(new Note_Info(read_text_node(nodeReader)));
                            break;
                        case "DC.SUBJECT":
                            if (nodeReader.HasAttributes)
                            {
                                nodeReader.MoveToAttribute(0);
                                string scheme = nodeReader.Value.Trim();
                                thisPackage.Bib_Info.Add_Subject(new Subject_Info_Standard(read_text_node(nodeReader), scheme));
                            }
                            else
                            {
                                thisPackage.Bib_Info.Add_Subject(new Subject_Info_Standard(read_text_node(nodeReader), String.Empty));
                            }
                            break;
                        case "PALMM.SPATIALNAME":
                            if (nodeReader.HasAttributes)
                            {
                                nodeReader.MoveToAttribute(0);
                                string scheme = nodeReader.Value.Trim();
                                Subject_Info_HierarchicalGeographic thisSpatial = new Subject_Info_HierarchicalGeographic();
                                thisSpatial.Authority = scheme;
                                thisSpatial.Area = read_text_node(nodeReader);
                                thisPackage.Bib_Info.Add_Subject(thisSpatial);
                            }
                            else
                            {
                                Subject_Info_HierarchicalGeographic thisSpatial = new Subject_Info_HierarchicalGeographic();
                                thisSpatial.Area = read_text_node(nodeReader);
                                thisPackage.Bib_Info.Add_Subject(thisSpatial);
                            }
                            break;
                        case "DC.FORMAT.EXTENT":
                            thisPackage.Bib_Info.Original_Description.Extent = read_text_node(nodeReader);
                            break;
                        case "DC.TYPE":
                            if (thisPackage.Bib_Info.Original_Description.Extent.Length > 0)
                            {
                                thisPackage.Bib_Info.Original_Description.Extent = read_text_node(nodeReader) + " ( " + thisPackage.Bib_Info.Original_Description.Extent + " )";
                            }
                            else
                            {
                                thisPackage.Bib_Info.Original_Description.Extent = read_text_node(nodeReader);
                            }
                            break;
                        case "PALMM.LOCATION":
                            thisPackage.Bib_Info.Location.Holding_Name = read_text_node(nodeReader);
                            break;
                        case "PALMM.NOTES":
                            thisPackage.Bib_Info.Add_Note(read_text_node(nodeReader));
                            break;
                    }
                }
            }
        }
        private static void Add_Hierarchical_Subject(Bibliographic_Info thisBibInfo, MARC_Record record, int tag)
        {
            int subj_index = 1;

            foreach (MARC_Field thisRecord in record[tag])
            {
                Subject_Info_HierarchicalGeographic spatial = new Subject_Info_HierarchicalGeographic();

                // Look for 'a' first
                if (thisRecord.has_Subfield('a'))
                {
                    spatial.Country = Remove_Trailing_Punctuation(thisRecord['a']);
                }

                // Look for 'b' next
                if (thisRecord.has_Subfield('b'))
                {
                    spatial.State = Remove_Trailing_Punctuation(thisRecord['b']);
                }

                // Look for 'c' next
                if (thisRecord.has_Subfield('c'))
                {
                    spatial.County = Remove_Trailing_Punctuation(thisRecord['c']);
                }

                // Look for 'd' next
                if (thisRecord.has_Subfield('d'))
                {
                    spatial.City = Remove_Trailing_Punctuation(thisRecord['d']);
                }

                // Look for area
                if (thisRecord.has_Subfield('f'))
                {
                    spatial.Area = Remove_Trailing_Punctuation(thisRecord['f']);
                }

                // Look for authority
                if (thisRecord.has_Subfield('2'))
                {
                    spatial.Authority = thisRecord['2'];
                }

                // Now, add to the object
                spatial.ID = "SUBJ" + tag + "_" + subj_index;
                subj_index++;
                thisBibInfo.Add_Subject(spatial);
            }
        }
        /// <summary> Saves the data rendered by this element to the provided bibliographic object during postback </summary>
        /// <param name="Bib"> Object into which to save the user's data, entered into the html rendered by this element </param>
        public override void Save_To_Bib(SobekCM_Item Bib)
        {
            string[] getKeys = HttpContext.Current.Request.Form.AllKeys;
            foreach (string thisKey in getKeys)
            {
                if (thisKey.IndexOf("formspatialcontinent_") == 0)
                {
                    string diff = thisKey.Replace("formspatialcontinent_", "");
                    string continent = HttpContext.Current.Request.Form[thisKey];
                    string country = HttpContext.Current.Request.Form["formspatialcountry_" + diff].Trim();
                    string province = HttpContext.Current.Request.Form["formspatialprovince_" + diff].Trim();
                    string region = HttpContext.Current.Request.Form["formspatialregion_" + diff].Trim();
                    string state = HttpContext.Current.Request.Form["formspatialstate_" + diff].Trim();
                    string territory = HttpContext.Current.Request.Form["formspatialterritory_" + diff].Trim();
                    string county = HttpContext.Current.Request.Form["formspatialcounty_" + diff].Trim();
                    string city = HttpContext.Current.Request.Form["formspatialcity_" + diff].Trim();
                    string citysection = HttpContext.Current.Request.Form["formspatialsectioncity_" + diff].Trim();
                    string island = HttpContext.Current.Request.Form["formspatialisland_" + diff].Trim();
                    string area = HttpContext.Current.Request.Form["formspatialarea_" + diff].Trim();

                    string authority = HttpContext.Current.Request.Form["formspatialauthority_" + diff].Trim();
                    string language = HttpContext.Current.Request.Form["formspatiallanguage_" + diff].Trim();

                    string type = HttpContext.Current.Request.Form["formspatialtype_" + diff].Trim();

                    if ((area.Length > 0) || (continent.Length > 0) || (country.Length > 0) || (province.Length > 0) ||
                        (region.Length > 0) || (state.Length > 0) || (territory.Length > 0) || (county.Length > 0) ||
                        (city.Length > 0) || (island.Length > 0))
                    {
                        Subject_Info_HierarchicalGeographic newSubject = new Subject_Info_HierarchicalGeographic
                                                                             {
                                                                                 Continent = continent,
                                                                                 Country = country,
                                                                                 Province = province,
                                                                                 Region = region,
                                                                                 State = state,
                                                                                 Territory = territory,
                                                                                 County = county,
                                                                                 City = city,
                                                                                 CitySection = citysection,
                                                                                 Island = island,
                                                                                 Area = area,
                                                                                 Authority = authority,
                                                                                 Language = language,
                                                                                 ID = type == "addedentry" ? "SUBJ752" : "SUBJ662"
                                                                             };

                        Bib.Bib_Info.Add_Subject(newSubject);
                    }
                }
            }
        }
        private static void read_subject_object(XmlReader r, Bibliographic_Info thisBibInfo)
        {
            string language = String.Empty;
            string authority = String.Empty;
            string id = String.Empty;

            if (r.MoveToAttribute("ID"))
                id = r.Value;
            if (r.MoveToAttribute("lang"))
                language = r.Value;
            if (r.MoveToAttribute("authority"))
                authority = r.Value;

            // Move to the next element
            while (r.Read())
            {
                if (r.NodeType == XmlNodeType.Element)
                    break;
            }

            // Determine the subject type
            Subject_Info_Type type = Subject_Info_Type.UNKNOWN;

            // What is the name of this node?
            switch (r.Name)
            {
                case "mods:topic":
                case "mods:geographic":
                case "mods:genre":
                case "mods:temporal":
                case "mods:occupation":
                case "topic":
                case "geographic":
                case "genre":
                case "temporal":
                case "occupation":
                    type = Subject_Info_Type.Standard;
                    break;

                case "mods:hierarchicalGeographic":
                case "hierarchicalGeographic":
                    type = Subject_Info_Type.Hierarchical_Spatial;
                    break;

                case "mods:cartographics":
                case "cartographics":
                    type = Subject_Info_Type.Cartographics;
                    break;

                case "mods:name":
                case "name":
                    type = Subject_Info_Type.Name;
                    break;

                case "mods:titleInfo":
                case "titleInfo":
                    type = Subject_Info_Type.TitleInfo;
                    break;
            }

            // If no type was determined, return null
            if (type == Subject_Info_Type.UNKNOWN)
                return;

            // Was this the standard subject object?
            if (type == Subject_Info_Type.Standard)
            {
                Subject_Info_Standard standardSubject = new Subject_Info_Standard();
                standardSubject.Language = language;
                standardSubject.Authority = authority;
                standardSubject.ID = id;

                do
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        if ((standardSubject.Topics_Count > 0) || (standardSubject.Geographics_Count > 0) || (standardSubject.Genres_Count > 0) ||
                            (standardSubject.Temporals_Count > 0) || (standardSubject.Occupations_Count > 0))
                        {
                            thisBibInfo.Add_Subject(standardSubject);
                        }
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:topic":
                            case "topic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Topic(r.Value);
                                break;

                            case "mods:geographic":
                            case "geographic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Geographic(r.Value);
                                break;

                            case "mods:genre":
                            case "genre":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Genre(r.Value);
                                break;

                            case "mods:temporal":
                            case "temporal":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Temporal(r.Value);
                                break;

                            case "mods:occupation":
                            case "occupation":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    standardSubject.Add_Occupation(r.Value);
                                break;
                        }
                    }
                } while (r.Read());
            }

            // Was this the hierarchical geography subject?
            if (type == Subject_Info_Type.Hierarchical_Spatial)
            {
                Subject_Info_HierarchicalGeographic geoSubject = new Subject_Info_HierarchicalGeographic();
                geoSubject.Language = language;
                geoSubject.Authority = authority;
                geoSubject.ID = id;

                while (r.Read())
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        thisBibInfo.Add_Subject(geoSubject);
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:continent":
                            case "continent":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Continent = r.Value;
                                break;

                            case "mods:country":
                            case "country":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Country = r.Value;
                                break;

                            case "mods:province":
                            case "province":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Province = r.Value;
                                break;

                            case "mods:region":
                            case "region":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Region = r.Value;
                                break;

                            case "mods:state":
                            case "state":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.State = r.Value;
                                break;

                            case "mods:territory":
                            case "territory":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Territory = r.Value;
                                break;

                            case "mods:county":
                            case "county":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.County = r.Value;
                                break;

                            case "mods:city":
                            case "city":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.City = r.Value;
                                break;

                            case "mods:citySection":
                            case "citySection":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.CitySection = r.Value;
                                break;

                            case "mods:island":
                            case "island":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Island = r.Value;
                                break;

                            case "mods:area":
                            case "area":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    geoSubject.Area = r.Value;
                                break;
                        }
                    }
                }
            }

            // Was this the cartographics subject?
            if (type == Subject_Info_Type.Cartographics)
            {
                Subject_Info_Cartographics mapSubject = new Subject_Info_Cartographics();
                mapSubject.Language = language;
                mapSubject.Authority = authority;
                mapSubject.ID = id;

                while (r.Read())
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        if ((mapSubject.Projection.Length > 0) || (mapSubject.Coordinates.Length > 0) || (mapSubject.Scale.Length > 0))
                        {
                            thisBibInfo.Add_Subject(mapSubject);
                        }
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:coordinates":
                            case "coordinates":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    mapSubject.Coordinates = r.Value;
                                break;

                            case "mods:scale":
                            case "scale":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    mapSubject.Scale = r.Value;
                                break;

                            case "mods:projection":
                            case "projection":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    mapSubject.Projection = r.Value;
                                break;
                        }
                    }
                }
            }

            // Was this the name subject?
            if (type == Subject_Info_Type.Name)
            {
                Subject_Info_Name nameSubject = new Subject_Info_Name();
                nameSubject.Language = language;
                nameSubject.Authority = authority;
                nameSubject.ID = id;

                do
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        thisBibInfo.Add_Subject(nameSubject);
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:name":
                            case "name":
                                Name_Info nameInfo = read_name_object(r);
                                nameSubject.Set_Internal_Name(nameInfo);
                                break;

                            case "mods:topic":
                            case "topic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Topic(r.Value);
                                break;

                            case "mods:geographic":
                            case "geographic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Geographic(r.Value);
                                break;

                            case "mods:genre":
                            case "genre":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Genre(r.Value);
                                break;

                            case "mods:temporal":
                            case "temporal":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    nameSubject.Add_Temporal(r.Value);
                                break;
                        }
                    }
                } while (r.Read());
            }

            // Was this the title subject?
            if (type == Subject_Info_Type.TitleInfo)
            {
                Subject_Info_TitleInfo titleSubject = new Subject_Info_TitleInfo();
                titleSubject.Language = language;
                titleSubject.Authority = authority;
                titleSubject.ID = id;

                do
                {
                    if ((r.NodeType == XmlNodeType.EndElement) && ((r.Name == "mods:subject") || (r.Name == "subject")))
                    {
                        thisBibInfo.Add_Subject(titleSubject);
                        return;
                    }

                    if (r.NodeType == XmlNodeType.Element)
                    {
                        switch (r.Name)
                        {
                            case "mods:titleInfo":
                            case "titleInfo":
                                Title_Info titleInfo = read_title_object(r);
                                titleSubject.Set_Internal_Title(titleInfo);
                                break;

                            case "mods:topic":
                            case "topic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Topic(r.Value);
                                break;

                            case "mods:geographic":
                            case "geographic":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Geographic(r.Value);
                                break;

                            case "mods:genre":
                            case "genre":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Genre(r.Value);
                                break;

                            case "mods:temporal":
                            case "temporal":
                                r.Read();
                                if (r.NodeType == XmlNodeType.Text)
                                    titleSubject.Add_Temporal(r.Value);
                                break;
                        }
                    }
                } while (r.Read());
            }
        }
        private static Subject_Info_HierarchicalGeographic Guarantee_Hierarchical_Spatial(SobekCM_Item Package)
        {
            // Is there an existing hierarchical?
            if (Package.Bib_Info.Subjects_Count > 0)
            {
                foreach (Subject_Info subject in Package.Bib_Info.Subjects)
                {
                    if (subject.Class_Type == Subject_Info_Type.Hierarchical_Spatial)
                    {
                        return (Subject_Info_HierarchicalGeographic) subject;
                    }
                }
            }

            // Add a spatial, if none exists
            Subject_Info_HierarchicalGeographic hierarchical = new Subject_Info_HierarchicalGeographic();
            Package.Bib_Info.Add_Subject(hierarchical);
            return hierarchical;
        }
        /// <summary> Add a new empty hierarchical geographic subject and return it  </summary>
        /// <returns>Newly built hierarchical geographic subject</returns>
        public Subject_Info_HierarchicalGeographic Add_Hierarchical_Geographic_Subject()
        {
            if (subjects == null)
                subjects = new List<Subject_Info>();

            Subject_Info_HierarchicalGeographic returnValue = new Subject_Info_HierarchicalGeographic();
            subjects.Add(returnValue);
            return returnValue;
        }