/// <summary> Constructor for a new instance of this class </summary>
        /// <param name="fields"> Fields which will be added to each record created </param>
        /// <param name="inputFile"> Text of the input file </param>
        /// <param name="outputFile"> Text for the output file as well </param>
        public MARC_Importer_Processor(string inputFile, bool JustSaveMarcXML, string ProjectCode, Constant_Fields constantCollection, bool Preview_Mode, string Error_Folder )
            : base(constantCollection)
        {
            // Save the parameters
            this.inputFile = inputFile;
            this.JustSaveMarcXML = JustSaveMarcXML;
            this.projectCode = ProjectCode;
            this.preview_mode = Preview_Mode;
            this.error_folder = Error_Folder;

            // Allow overlay from MARC records
            base.allow_overlay = true;

            // Create the parser
            parser = new MARC21_Exchange_Format_Parser();

            // Set the MARC directory and the error directory
            marc_directory = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\SMaRT\\MarcXML\\";
            error_folder = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\SMaRT\\Temporary\\";

            // Ensure both folders exist
            if (!Directory.Exists(marc_directory))
                Directory.CreateDirectory(marc_directory);
            if (!Directory.Exists(error_folder))
                Directory.CreateDirectory(error_folder);
        }
        /// <summary> Constructor for a new instance of this class </summary>
        /// <param name="fields"> Fields which will be added to each record created </param>
        /// <param name="inputFile"> Text of the input file </param>
        /// <param name="outputFile"> Text for the output file as well </param>
        public MARC_Importer_Processor(string inputFile, bool JustSaveMarcXML, string ProjectCode, Constant_Fields constantCollection, bool Preview_Mode, string Error_Folder) : base(constantCollection)
        {
            // Save the parameters
            this.inputFile       = inputFile;
            this.JustSaveMarcXML = JustSaveMarcXML;
            this.projectCode     = ProjectCode;
            this.preview_mode    = Preview_Mode;
            this.error_folder    = Error_Folder;

            // Allow overlay from MARC records
            base.allow_overlay = true;

            // Create the parser
            parser = new MARC21_Exchange_Format_Parser();

            // Set the MARC directory and the error directory
            marc_directory = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\SMaRT\\MarcXML\\";
            error_folder   = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "\\SMaRT\\Temporary\\";

            // Ensure both folders exist
            if (!Directory.Exists(marc_directory))
            {
                Directory.CreateDirectory(marc_directory);
            }
            if (!Directory.Exists(error_folder))
            {
                Directory.CreateDirectory(error_folder);
            }
        }
        /// <summary> DEMO 2: Read the second record from a MARC21 DAT file, w/o using the IEnumerator
        /// interface and write that single record to both a XML file and a DAT file, w/o calling the writer classes
        /// explicitly </summary>
        private static void demo2()
        {
            Console.WriteLine("Performing demo2");

            // Create the marc21 exchange reader
            MARC21_Exchange_Format_Parser parser1 = new MARC21_Exchange_Format_Parser();

            // This parses and pulls out the first record (discarded)
            parser1.Parse("CIMMYT01.dat");

            // We'll pull again to get the second
            MARC_Record record = parser1.Next();

            // If this is null, say so
            if (record == null)
            {
                Console.WriteLine("Unable to read the second record from test file.");
                return;
            }

            // Save as a MarcXML file
            if (!record.Save_MARC_XML("demo2.xml"))
            {
                Console.WriteLine("Error encountered while writing demo2.xml");
                return;
            }

            // Save as a single Marc21 file
            if (!record.Save_MARC21("demo2.dat"))
            {
                Console.WriteLine("Error encountered while writing demo2.dat");
            }
        }
        /// <summary> DEMO 1 : Read a MARC DAT file completely using the IEnumerator interface. and adding it to  a MarcXML output file </summary>
        private static void demo1()
        {
            Console.WriteLine("Performing demo1");

            // Create the marc21 exchange reader
            MARC21_Exchange_Format_Parser parser1 = new MARC21_Exchange_Format_Parser("AgricNewCat02.dat");

            // Create the marc xml writer
            MARCXML_Writer writer1 = new MARCXML_Writer("AgricNewCat02.xml");

            try
            {
                // Step through each record from the Marc21 dat file and output to the XML file
                foreach (MARC_Record thisRecord in parser1)
                {
                    writer1.AppendRecord(thisRecord);
                }
            }
            catch (Exception ee)
            {
                Console.WriteLine(ee.StackTrace);
            }
            finally
            {
                // Close all the streams
                parser1.Close();
                writer1.Close();
            }
        }
        /// <summary> DEMO 3: Read the resulting demo2.dat file, change the title, publisher, and add
        /// a subject field and then save it again</summary>
        private static void demo3()
        {
            Console.WriteLine("Performing demo3");

            // Create the marc21 exchange reader
            MARC21_Exchange_Format_Parser parser1 = new MARC21_Exchange_Format_Parser();

            // Read the record
            MARC_Record record = parser1.Parse("demo2.dat");

            // If this is null, say so
            if (record == null)
            {
                Console.WriteLine("Unable to read the demo2.dat in the 3rd demo portion");
                return;
            }

            // Change the title field ( 245 )
            record[245][0].Add_NonRepeatable_Subfield('a', "New Title");

            // Also change the creator field (110 in this case)
            record[110][0].Add_NonRepeatable_Subfield('a', "Corn Maze Production, Incorporated");

            // Add a new field to record
            MARC_Field newSubject = record.Add_Field(650, ' ', '0');

            newSubject.Add_Subfield('a', "Soils");
            newSubject.Add_Subfield('x', "Phosphorous content");
            newSubject.Add_Subfield('z', "Indonesia");

            // Save this as XML and also as Marc21
            record.Save_MARC_XML("demo3.xml");
            record.Save_MARC21("demo3.dat");
        }
        /// <summary> Constructor for a new instance of this class </summary>
        /// <param name="fields"> Fields which will be added to each record created </param>
        /// <param name="inputFile"> Text of the input file </param>
        /// <param name="outputFile"> Text for the output file as well </param>
        public MARC_Importer_Processor(string inputFile, Constant_Fields constantCollection, string Destination_Folder, string BibID_Start, int First_BibID)
            : base(constantCollection)
        {
            // Save the parameters
            this.inputFile     = inputFile;
            destination_folder = Destination_Folder;
            bibid_start        = BibID_Start;
            next_bibid_counter = First_BibID;

            // Allow overlay from MARC records
            base.allow_overlay = true;

            // Create the parser
            parser = new MARC21_Exchange_Format_Parser();

            // Set the error and marc subfolders
            marc_folder  = destination_folder + "\\MARC";
            error_folder = destination_folder + "\\Error";
        }
        public static MARC_Record Get_Record_By_Primary_Identifier(string Primary_Identifier, Z3950_Endpoint Z3950_Server, out string Message, Record_Character_Encoding encoding)
        {
            // Initially set the message to empty
            Message = String.Empty;

            // http://jai-on-asp.blogspot.com/2010/01/z3950-client-in-cnet-using-zoomnet-and.html
            // http://www.indexdata.com/yaz/doc/tools.html#PQF
            // http://www.loc.gov/z3950/agency/defns/bib1.html
            // http://www.assembla.com/code/wasolic/subversion/nodes/ZOOM.NET
            // http://lists.indexdata.dk/pipermail/yazlist/2007-June/002080.html
            // http://fclaweb.fcla.edu/content/z3950-access-aleph

            const string prefix = "@attrset Bib-1 @attr 1=12 ";

            try
            {
                IConnection  connection; //	zoom db connector
                IPrefixQuery query;      //	zoom query
                IRecord      record;     //	one zoom record
                IResultSet   records;    //	collection of records

                //	allocate MARC tools
                MARC21_Exchange_Format_Parser parser = new MARC21_Exchange_Format_Parser();

                //	establish connection
                connection = new Connection(Z3950_Server.URI, Convert.ToInt32(Z3950_Server.Port));
                connection.DatabaseName = Z3950_Server.Database_Name;

                // Any authentication here?
                if (Z3950_Server.Username.Length > 0)
                {
                    connection.Username = Z3950_Server.Username;
                }
                if (Z3950_Server.Password.Length > 0)
                {
                    connection.Password = Z3950_Server.Password;
                }

                // Set to USMARC
                connection.Syntax = RecordSyntax.USMARC;

                //	call the Z39.50 server
                query   = new PrefixQuery(prefix + Primary_Identifier);
                records = connection.Search(query);

                // If the record count is not one, return a message
                if (records.Count != 1)
                {
                    if (records.Count == 0)
                    {
                        Message = "ERROR: No matching record found in Z39.50 endpoint";
                    }
                    else
                    {
                        Message = "ERROR: More than one matching record found in Z39.50 endpoint by primary identifier";
                    }
                    return(null);
                }

                //	capture the byte stream
                record = records[0];
                MemoryStream ms = new MemoryStream(record.Content);

                //	display while debugging
                //MessageBox.Show(Encoding.UTF8.GetString(record.Content));

                try
                {
                    //	feed the record to the parser and add the 955
                    MARC_Record marcrec = parser.Parse(ms, encoding);
                    parser.Close();
                    return(marcrec);
                }
                catch (Exception error)
                {
                    Message = "ERROR: Unable to parse resulting record into the MARC Record structure!\n\n" + error.Message;
                    return(null);
                    //MessageBox.Show("Could not convert item " + Primary_Identifier + " to MARCXML.");
                    //Trace.WriteLine("Could not convert item " + Primary_Identifier   + " to MARCXML.");
                    //Trace.WriteLine("Error details: " + error.Message);
                }
            }
            catch (Exception error)
            {
                if (error.Message.IndexOf("The type initializer for 'Zoom.Net.Yaz") >= 0)
                {
                    Message = "ERROR: The Z39.50 libraries did not correctly initialize.\n\nThese libraries do not currently work in 64-bit environments.";
                }
                else
                {
                    Message = "ERROR: Unable to connect and search provided Z39.50 endpoint.\n\n" + error.Message;
                }

                return(null);
                //MessageBox.Show("Could not convert item " + Primary_Identifier + " to MARCXML.");
                //Trace.WriteLine("Could not convert item " + Primary_Identifier   + " to MARCXML.");
                //Trace.WriteLine("Error details: " + error.Message);
            }
        }
        /// <summary> Gets a MARC record from a Z39.50 server, by performaing a search </summary>
        /// <param name="Attribute_Number"> Z39.50 attribute number which indicates against which metadata field search should occur </param>
        /// <param name="Search_Term"> Term to search for within the attribute number </param>
        /// <param name="Z3950_Server"> Z39.50 server endpoint information </param>
        /// <param name="Message"> Return message from the server </param>
        /// <returns> MARC record, if retrievable by search </returns>
        public static MARC_Record Get_Record(int Attribute_Number, string Search_Term, Z3950_Endpoint Z3950_Server, out string Message)
        {
            // Initially set the message to empty
            Message = String.Empty;

            // http://jai-on-asp.blogspot.com/2010/01/z3950-client-in-cnet-using-zoomnet-and.html
            // http://www.indexdata.com/yaz/doc/tools.html#PQF
            // http://www.loc.gov/z3950/agency/defns/bib1.html
            // http://www.assembla.com/code/wasolic/subversion/nodes/ZOOM.NET
            // http://lists.indexdata.dk/pipermail/yazlist/2007-June/002080.html
            // http://fclaweb.fcla.edu/content/z3950-access-aleph

            string prefix = "@attrset Bib-1 @attr 1=" + Attribute_Number + " ";

            try
            {
                //	allocate MARC tools
                MARC21_Exchange_Format_Parser parser = new MARC21_Exchange_Format_Parser();

                //	establish connection
                IConnection connection = new Connection(Z3950_Server.URI, Convert.ToInt32(Z3950_Server.Port));
                connection.DatabaseName = Z3950_Server.Database_Name;

                // Any authentication here?
                if (Z3950_Server.Username.Length > 0)
                    connection.Username = Z3950_Server.Username;
                if (Z3950_Server.Password.Length > 0)
                    connection.Password = Z3950_Server.Password;

                // Set to USMARC
                connection.Syntax = RecordSyntax.USMARC;

                //	call the Z39.50 server
                IPrefixQuery query = new PrefixQuery(prefix + Search_Term);
                IResultSet records = connection.Search(query);

                // If the record count is not one, return a message
                if (records.Count != 1)
                {
                    Message = records.Count == 0 ? "ERROR: No matching record found in Z39.50 endpoint" : "ERROR: More than one matching record found in Z39.50 endpoint by ISBN";
                    return null;
                }

                //	capture the byte stream
                IRecord record = records[0];
                MemoryStream ms = new MemoryStream(record.Content);

                //	display while debugging
                //MessageBox.Show(Encoding.UTF8.GetString(record.Content));

                try
                {
                    //	feed the record to the parser and add the 955
                    MARC_Record marcrec = parser.Parse(ms);
                    parser.Close();
                    return marcrec;
                }
                catch (Exception error)
                {
                    Message = "ERROR: Unable to parse resulting record into the MARC Record structure!\n\n" + error.Message;
                    return null;
                    //MessageBox.Show("Could not convert item " + Primary_Identifier + " to MARCXML.");
                    //Trace.WriteLine("Could not convert item " + Primary_Identifier   + " to MARCXML.");
                    //Trace.WriteLine("Error details: " + error.Message);
                }
            }
            catch (Exception error)
            {
                if (error.Message.IndexOf("The type initializer for 'Zoom.Net.Yaz") >= 0)
                {
                    Message = "ERROR: The Z39.50 libraries did not correctly initialize.\n\nThese libraries do not currently work in 64-bit environments.";
                }
                else
                {
                    Message = "ERROR: Unable to connect and search provided Z39.50 endpoint.\n\n" + error.Message;
                }

                return null;
                //MessageBox.Show("Could not convert item " + Primary_Identifier + " to MARCXML.");
                //Trace.WriteLine("Could not convert item " + Primary_Identifier   + " to MARCXML.");
                //Trace.WriteLine("Error details: " + error.Message);
            }
        }