private static void Add_Corporate_Name(Bibliographic_Info thisBibInfo, MARC_Record record, int tag, int name_type)
        {
            // Step through each instance of this tag
            foreach (MARC_Field thisRecord in record[tag])
            {
                if ((name_type != 3) || (thisRecord.Indicator2 == '3'))
                {
                    // Create the name object
                    Name_Info newName = new Name_Info();
                    newName.Name_Type = Name_Info_Type_Enum.Corporate;

                    // Only continue if there is an id in this record
                    if ((thisRecord.has_Subfield('a')) && (thisRecord['a'].ToUpper().IndexOf("PALMM") < 0))
                    {
                        newName.Full_Name = Remove_Trailing_Punctuation(thisRecord['a']);
                        if (thisRecord.has_Subfield('b'))
                        {
                            newName.Full_Name = newName.Full_Name + " -- " + Remove_Trailing_Punctuation(thisRecord['b']);
                        }
                        if (thisRecord.has_Subfield('c'))
                            newName.Description = thisRecord['c'];
                        if (thisRecord.has_Subfield('d'))
                            newName.Dates = Remove_Trailing_Punctuation(thisRecord['d']);
                        if (thisRecord.has_Subfield('e'))
                            newName.Add_Role(Remove_Trailing_Punctuation(thisRecord['e']));
                        if (thisRecord.has_Subfield('u'))
                            newName.Affiliation = Remove_Trailing_Punctuation(thisRecord['u']);

                        // Is there a relator code?
                        if (thisRecord.has_Subfield('4'))
                        {
                            // Get the relator code
                            string relatorcode = thisRecord['4'];
                            newName.Add_Role(relatorcode, "marcrelator", Name_Info_Role_Type_Enum.Code);
                        }

                        switch (name_type)
                        {
                            case 1:
                                thisBibInfo.Main_Entity_Name = newName;
                                break;

                            case 2:
                                thisBibInfo.Add_Named_Entity(newName);
                                break;

                            case 3:
                                thisBibInfo.Donor = newName;
                                break;

                            case 4:
                                Subject_Info_Name newNameSubj = new Subject_Info_Name();
                                newNameSubj.Set_Internal_Name(newName);
                                if (thisRecord.has_Subfield('v'))
                                    newNameSubj.Add_Genre(Remove_Trailing_Punctuation(thisRecord['v']));
                                if (thisRecord.has_Subfield('x'))
                                    newNameSubj.Add_Topic(Remove_Trailing_Punctuation(thisRecord['x']));
                                if (thisRecord.has_Subfield('y'))
                                    newNameSubj.Add_Temporal(Remove_Trailing_Punctuation(thisRecord['y']));
                                if (thisRecord.has_Subfield('z'))
                                    newNameSubj.Add_Geographic(Remove_Trailing_Punctuation(thisRecord['z']));
                                if (thisRecord.has_Subfield('2'))
                                    newNameSubj.Authority = thisRecord['2'];
                                switch (thisRecord.Indicator2)
                                {
                                    case '0':
                                        newNameSubj.Authority = "lcsh";
                                        break;

                                    case '1':
                                        newNameSubj.Authority = "lcshac";
                                        break;

                                    case '2':
                                        newNameSubj.Authority = "mesh";
                                        break;

                                    case '3':
                                        newNameSubj.Authority = "nal";
                                        break;

                                    case '5':
                                        newNameSubj.Authority = "csh";
                                        break;

                                    case '6':
                                        newNameSubj.Authority = "rvm";
                                        break;
                                }
                                break;
                        }
                    }
                }
            }
        }
        private static void Add_Personal_Name(Bibliographic_Info thisBibInfo, MARC_Record record, int tag, int name_type)
        {
            // Step through each instance of this tag
            foreach (MARC_Field thisRecord in record[tag])
            {
                // Create the name object
                Name_Info newName = new Name_Info();
                newName.Name_Type = Name_Info_Type_Enum.Personal;

                // Only continue if there is an id in this record
                if ((thisRecord.has_Subfield('a')) && (thisRecord['a'].ToUpper().IndexOf("PALMM") < 0))
                {
                    // Save the 'a' value
                    switch (thisRecord.Indicator1)
                    {
                        case '0':
                            newName.Given_Name = Remove_Trailing_Punctuation(thisRecord['a']);
                            newName.Full_Name = newName.Given_Name;
                            break;

                        case '1':
                            string tempName = Remove_Trailing_Punctuation(thisRecord['a']);
                            int tempCommaIndex = tempName.IndexOf(",");
                            if (tempCommaIndex > 0)
                            {
                                newName.Family_Name = tempName.Substring(0, tempCommaIndex).Trim();
                                newName.Given_Name = tempName.Substring(tempCommaIndex + 1).Trim();
                                newName.Full_Name = tempName;
                            }
                            else
                            {
                                newName.Family_Name = tempName;
                            }
                            break;

                        case '3':
                            newName.Family_Name = Remove_Trailing_Punctuation(thisRecord['a']);
                            newName.Full_Name = newName.Family_Name;
                            break;

                        default:
                            newName.Full_Name = Remove_Trailing_Punctuation(thisRecord['a']);
                            break;
                    }

                    if (thisRecord.has_Subfield('b'))
                        newName.Terms_Of_Address = thisRecord['b'];
                    if (thisRecord.has_Subfield('c'))
                    {
                        if (newName.Terms_Of_Address.Length > 0)
                        {
                            newName.Terms_Of_Address = newName.Terms_Of_Address + "; " + thisRecord['c'];
                        }
                        else
                        {
                            newName.Terms_Of_Address = thisRecord['c'];
                        }
                    }
                    if (thisRecord.has_Subfield('d'))
                        newName.Dates = Remove_Trailing_Punctuation(thisRecord['d']);
                    if (thisRecord.has_Subfield('e'))
                        newName.Add_Role(Remove_Trailing_Punctuation(thisRecord['e']));
                    if (thisRecord.has_Subfield('g'))
                        newName.Description = Remove_Trailing_Punctuation(thisRecord['g']);
                    if (thisRecord.has_Subfield('j'))
                    {
                        if (newName.Description.Length > 0)
                        {
                            newName.Description = newName.Description + "; " + thisRecord['j'];
                        }
                        else
                        {
                            newName.Description = thisRecord['j'];
                        }
                    }
                    if (thisRecord.has_Subfield('u'))
                        newName.Affiliation = Remove_Trailing_Punctuation(thisRecord['u']);
                    if (thisRecord.has_Subfield('q'))
                        newName.Display_Form = Remove_Trailing_Punctuation(thisRecord['q'].Replace("(", "").Replace(")", ""));

                    // Is there a relator code?
                    if (thisRecord.has_Subfield('4'))
                    {
                        // Get the relator code
                        string completeRelatorcode = thisRecord['4'];
                        string[] relatorCodesSplitter = completeRelatorcode.Split("|".ToCharArray());
                        foreach (string relatorcode in relatorCodesSplitter)
                        {
                            newName.Add_Role(relatorcode, "marcrelator", Name_Info_Role_Type_Enum.Code);
                        }
                    }

                    switch (name_type)
                    {
                        case 1:
                            thisBibInfo.Main_Entity_Name = newName;
                            break;

                        case 2:
                            thisBibInfo.Add_Named_Entity(newName);
                            break;

                        case 3:
                            thisBibInfo.Donor = newName;
                            break;

                        case 4:
                            Subject_Info_Name newNameSubj = new Subject_Info_Name();
                            newNameSubj.Set_Internal_Name(newName);
                            if (thisRecord.has_Subfield('v'))
                                newNameSubj.Add_Genre(Remove_Trailing_Punctuation(thisRecord['v']));
                            if (thisRecord.has_Subfield('x'))
                                newNameSubj.Add_Topic(Remove_Trailing_Punctuation(thisRecord['x']));
                            if (thisRecord.has_Subfield('y'))
                                newNameSubj.Add_Temporal(Remove_Trailing_Punctuation(thisRecord['y']));
                            if (thisRecord.has_Subfield('z'))
                                newNameSubj.Add_Geographic(Remove_Trailing_Punctuation(thisRecord['z']));
                            if (thisRecord.has_Subfield('2'))
                                newNameSubj.Authority = thisRecord['2'];
                            switch (thisRecord.Indicator2)
                            {
                                case '0':
                                    newNameSubj.Authority = "lcsh";
                                    break;

                                case '1':
                                    newNameSubj.Authority = "lcshac";
                                    break;

                                case '2':
                                    newNameSubj.Authority = "mesh";
                                    break;

                                case '3':
                                    newNameSubj.Authority = "nal";
                                    break;

                                case '5':
                                    newNameSubj.Authority = "csh";
                                    break;

                                case '6':
                                    newNameSubj.Authority = "rvm";
                                    break;
                            }
                            break;
                    }
                }
            }
        }
        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());
            }
        }