/**
         * Translate the data line to a {@link MZTabRecord}.
         *
         * NOTICE: Normally, we suggest user do convert operation after validate successfully.
         *
         * @see #parse(int, string, uk.ac.ebi.pride.jmztab.utils.errors.MZTabErrorList)
         */
        protected MZTabRecord getRecord(Section section, string line)
        {
            MZTabRecord record = null;

            if (section.Equals(Section.Protein)){
                record = new Protein(factory);
            }
            else if (section.Equals(Section.Peptide)){
                record = new Peptide(factory, metadata);
            }
            else if (section.Equals(Section.PSM)){
                record = new PSM(factory, metadata);
            }
            else if (section.Equals(Section.Small_Molecule)){
                record = new SmallMolecule(factory, metadata);
            }

            int offset = loadStableData(record, line);
            if (offset == _items.Length - 1){
                return record;
            }

            loadOptionalData(record, offset);

            return record;
        }
        /**
         * Add a Protein record.
         *
         * @param protein SHOULD NOT set null.
         */
        public void addProtein(Protein protein)
        {
            if (protein == null){
                throw new NullReferenceException("Protein record is null!");
            }

            int lineNumber = proteins.Count == 0 ? 1 : proteins.Last().Key + 1;
            proteins.Add(lineNumber, protein);
        }
        /**
         * Add a Protein record.
         *
         * @param lineNumber SHOULD be positive integer
         * @param protein SHOULD NOT set null.
         *
         * @throws ArgumentException  if there exists Protein object for assigned lineNumber
         */
        public void addProtein(int lineNumber, Protein protein)
        {
            if (protein == null){
                throw new NullReferenceException("Protein record is null!");
            }
            if (lineNumber <= 0){
                throw new ArgumentException("Line number should be positive integer");
            }
            if (proteins.ContainsKey(lineNumber)){
                throw new ArgumentException("There already exist protein record in line number " + lineNumber);
            }

            proteins.Add(lineNumber, protein);
        }
        private void addProteinValue()
        {
            MsRun msRun1 = new MsRun(1);
            MsRun msRun2 = new MsRun(2);
            Assay assay1 = new Assay(1);
            Assay assay2 = new Assay(2);
            StudyVariable studyVariable1 = new StudyVariable(1);

            MZTabColumnFactory factory = MZTabColumnFactory.GetInstance(Section.Protein_Header);
            factory.AddOptionalColumn(ProteinColumn.SEARCH_ENGINE_SCORE, msRun1);
            factory.AddOptionalColumn(ProteinColumn.NUM_PSMS, msRun1);
            factory.AddOptionalColumn(ProteinColumn.NUM_PEPTIDES_DISTINCT, msRun1);
            factory.AddOptionalColumn(ProteinColumn.NUM_PEPTIDES_UNIQUE, msRun1);
            factory.AddOptionalColumn(ProteinColumn.NUM_PSMS, msRun2);
            factory.AddOptionalColumn(ProteinColumn.NUM_PEPTIDES_DISTINCT, msRun2);

            factory.AddAbundanceOptionalColumn(assay1);
            factory.AddAbundanceOptionalColumn(studyVariable1);
            factory.AddAbundanceOptionalColumn(assay2);

            factory.AddOptionalColumn(assay1, "my_value", typeof (string));
            CVParam param = new CVParam("MS", "MS:1002217", "decoy peptide", null);
            factory.AddOptionalColumn(param, typeof (string));

            Console.WriteLine(factory);

            Protein protein = new Protein(factory);

            // set stable columns data.
            protein.Accession = "P12345";
            protein.Description = "Aspartate aminotransferase, mitochondrial";
            protein.SetTaxid("10116");
            protein.Species = "Rattus norvegicus (Rat)";
            protein.Database = "UniProtKB";
            protein.DatabaseVersion = "2011_11";
            protein.SetSearchEngine("[MS,MS:1001207,Mascot,]");
            protein.AddSearchEngine("[MS,MS:1001208,Sequest,]");
            protein.SetBestSearchEngineScore("[MS,MS:1001171,Mascot score,50]|[MS,MS:1001155,Sequest:xcorr,2]");
            protein.Reliability = Reliability.High;
            protein.SetAmbiguityMembers("P12347,P12348");
            protein.SetModifications("3|4|8-MOD:00412, 3|4|8-MOD:00412");
            protein.SetURI("http://www.ebi.ac.uk/pride/url/to/P12345");
            protein.SetGOTerms("GO:0006457|GO:0005759|GO:0005886|GO:0004069");
            protein.SetProteinCoverage("0.4");
            Console.WriteLine(protein);

            // set optional columns which have stable order.
            protein.setSearchEngineScore(msRun1, "[MS,MS:1001171,Mascot score,50]|[MS,MS:1001155,Sequest:xcorr,2]");
            protein.setNumPSMs(msRun1, 4);
            protein.setNumPSMs(msRun2, 2);
            protein.setNumPeptidesDistinct(msRun1, 3);
            protein.setNumPeptidesUnique(msRun1, 2);
            Console.WriteLine(protein);

            // set abundance columns
            protein.setAbundanceColumn(assay1, "0.4");
            protein.setAbundanceColumn(assay2, "0.2");

            protein.setAbundanceColumn(studyVariable1, "0.4");
            protein.setAbundanceStdevColumn(studyVariable1, "0.3");
            protein.setAbundanceStdErrorColumn(studyVariable1, "0.2");
            Console.WriteLine(protein);

            // set user defined optional columns
            protein.setOptionColumn(assay1, "my_value", "My value about assay[1]");
            protein.setOptionColumn(param, "TOM value");

            Console.WriteLine(protein);
        }