/// <summary>
        /// Read in the current transition groups's precursors and try to modernize the XML so that it's in terms of a common neutral
        /// molecule with adducts, while preserving the precursor mz values
        /// </summary>
        /// <param name="peptide">Neutral molecule associated with current reader position, may be replaced during this call</param>
        /// <returns>Reader positioned at end of current precursor opening, but using cached and possibly altered XML</returns>
        public XmlReader Read(ref Peptide peptide)
        {
            if (_precursorRawDetails.Count == 0)
            {
                return(ReadAhead.CreateXmlReader()); // No precursors to process
            }

            // Find a formula for the parent molecule, if possible
            ProposeMoleculeWithCommonFormula(peptide);

            // Deal with mass-only declarations if no formulas were found
            if (string.IsNullOrEmpty(ProposedMolecule.Formula))
            {
                return(HandleMassOnlyDeclarations(ref peptide));
            }

            // Check to see if description already makes sense
            if (_precursorRawDetails.TrueForAll(d =>
                                                !Adduct.IsNullOrEmpty(d._nominalAdduct) &&
                                                Math.Abs(d._declaredMz - d._nominalAdduct.MzFromNeutralMass(ProposedMolecule.MonoisotopicMass)) <= MzToler))
            {
                return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._nominalAdduct)));
            }

            // See if there are simple adducts that work with common formula
            if (DeriveAdductsForCommonFormula(peptide))
            {
                // Found a molecule that works for all precursors that declared a formula (though that may not be all precursors, users create highly variable documents)
                return(UpdatePeptideAndInsertAdductsInXML(ref peptide, _precursorRawDetails.Select(d => d._proposedAdduct)));
            }

            // Done adjusting parent molecule, must come up with rest of adducts to make mz and base molecule agree
            return(ConsiderMassShiftAdducts(ref peptide));
        }
        private XmlReader UpdatePeptideAndInsertAdductsInXML(ref Peptide peptide, IEnumerable <Adduct> adducts)
        {
            var updatedPeptide = ReferenceEquals(ProposedMolecule, peptide.CustomMolecule) ? peptide : new Peptide(ProposedMolecule);
            var ionFormulas    = adducts.Select(a => updatedPeptide.CustomMolecule.Formula + a.ToString()).ToList();

            ReadAhead.ModifyAttributesInElement(DocumentSerializer.EL.precursor, DocumentSerializer.ATTR.ion_formula,
                                                ionFormulas); // N.B. "ion_formula" consists of just the adduct for mass only molecules
            peptide = updatedPeptide;
            return(ReadAhead.CreateXmlReader());              // Return a reader that uses the updated XML
        }