PWIZ_API_DECL
msdata::SpectrumPtr SpectrumList_MZWindow::spectrum(size_t index, bool getBinaryData) const
{
    SpectrumPtr spectrum = inner_->spectrum(index, getBinaryData);
    if (!getBinaryData) return spectrum;

    vector<MZIntensityPair> data;
    spectrum->getMZIntensityPairs(data);

    vector<MZIntensityPair>::const_iterator begin = lower_bound(
        data.begin(), data.end(), MZIntensityPair(mzLow_,0), hasLowerMZ);

    vector<MZIntensityPair>::const_iterator end = upper_bound(
        data.begin(), data.end(), MZIntensityPair(mzHigh_,0), hasLowerMZ);

    vector<MZIntensityPair> newData;
    copy(begin, end, back_inserter(newData));

    BinaryDataArrayPtr intensityArray = spectrum->getIntensityArray();
    CVID intensityUnits = intensityArray.get() ? intensityArray->cvParam(MS_intensity_unit).cvid : CVID_Unknown;
    
    SpectrumPtr newSpectrum(new Spectrum(*spectrum));
    newSpectrum->binaryDataArrayPtrs.clear();
    newSpectrum->setMZIntensityPairs(newData, intensityUnits);

    return newSpectrum;
}
PWIZ_API_DECL SpectrumPtr SpectrumList_MetadataFixer::spectrum(size_t index, bool getBinaryData) const
{
    // always get binary data
    SpectrumPtr s = inner_->spectrum(index, true);

    BinaryDataArrayPtr mzArray = s->getMZArray();
    BinaryDataArrayPtr intensityArray = s->getIntensityArray();
    if (!mzArray.get() || !intensityArray.get())
        return s;

    vector<double>& mzs = mzArray->data;
    vector<double>& intensities = intensityArray->data;

    double tic = 0;
    if (!mzs.empty())
    {
        double bpmz, bpi = -1;
        for (size_t i=0, end=mzs.size(); i < end; ++i)
        {
            tic += intensities[i];
            if (bpi < intensities[i])
            {
                bpi = intensities[i];
                bpmz = mzs[i];
            }
        }

        replaceCvParam(*s, MS_base_peak_intensity, bpi, MS_number_of_counts);
        replaceCvParam(*s, MS_base_peak_m_z, bpmz, MS_m_z);
        replaceCvParam(*s, MS_lowest_observed_m_z, mzs.front(), MS_m_z);
        replaceCvParam(*s, MS_highest_observed_m_z, mzs.back(), MS_m_z);
    }

    replaceCvParam(*s, MS_TIC, tic, MS_number_of_counts);

    return s;
}