#TODO: docstring

    :param specfile: #TODO docstring
    :param msrunContainer: #TODO docstring
    :param outputdir: #TODO docstring
    :param spectrumIds: #TODO docstring
    :param chromatogramIds: #TODO docstring

def writeMzml(specfile, msrunContainer, outputdir, spectrumIds=None,
              chromatogramIds=None, writeIndex=True):
    """ #TODO: docstring

    :param specfile: #TODO docstring
    :param msrunContainer: #TODO docstring
    :param outputdir: #TODO docstring
    :param spectrumIds: #TODO docstring
    :param chromatogramIds: #TODO docstring
    """
    #TODO: maybe change to use aux.openSafeReplace
    outputFile = io.BytesIO()

    #TODO: perform check that specfile is present in msrunContainer and at least
    #   the metadatanode.
    metadataTree = msrunContainer.rmc[specfile]
    #Generate a list of spectrum ids that should be written to mzML
    if spectrumIds is None and specfile in msrunContainer.smic:
        keyTuple = [(int(key), key) for key in viewkeys(msrunContainer.smic[specfile])]
        spectrumIds = [key for _, key in sorted(keyTuple)]
    spectrumCounts = len(spectrumIds)
    #Generate a list of chromatogram ids that should be written to mzML
    if chromatogramIds is None and specfile in msrunContainer.cic:
        chromatogramIds = [cId for cId in viewkeys(msrunContainer.cic[specfile])]
    chromatogramCounts = len(chromatogramIds)

    spectrumIndexList = list()
    chromatogramIndexList = list()

    xmlFile = ETREE.xmlfile(outputFile, encoding='ISO-8859-1', buffered=False)
    xmlWriter = xmlFile.__enter__()
    xmlWriter.write_declaration()

    nsmap = {None: 'http://psi.hupo.org/ms/mzml',
             'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
             }
    mzmlAttrib = {'{http://www.w3.org/2001/XMLSchema-instance}schemaLocation': \
                    'http://psi.hupo.org/ms/mzml http://psidev.info/files/ms/mzML/xsd/mzML1.1.0.xsd',
                  'version': '1.1.0', 'id': metadataTree.attrib['id']
                  }

    if writeIndex:
        xmlIndexedMzml = xmlWriter.element('indexedmzML', nsmap=nsmap)
        xmlIndexedMzml.__enter__()
        xmlWriter.write('\n')
    xmlMzml = xmlWriter.element('mzML', mzmlAttrib, nsmap=nsmap)
    xmlMzml.__enter__()
    xmlWriter.write('\n')

    for metadataNode in metadataTree.getchildren():
        if metadataNode.tag != 'run':
            xmlWriter.write(maspy.xml.recCopyElement(metadataNode),
                            pretty_print=True
                            )
        else:
            xmlRun = xmlWriter.element(metadataNode.tag, metadataNode.attrib)
            xmlRun.__enter__()
            xmlWriter.write('\n')
            for runChild in metadataNode.getchildren():
                if runChild.tag == 'spectrumList':
                    specDefaultProcRef = runChild.attrib['defaultDataProcessingRef']
                elif runChild.tag == 'chromatogramList':
                    chromDefaultProcRef = runChild.attrib['defaultDataProcessingRef']
                else:
                    #TODO: maybe recCopy?
                    xmlRun.append(runChild)

            #If any spectra should be written, generate the spectrumList Node.
            if spectrumCounts > 0:
                specListAttribs = {'count': str(spectrumCounts),
                                   'defaultDataProcessingRef': specDefaultProcRef
                                   }
                xmlSpectrumList = xmlWriter.element('spectrumList',
                                                    specListAttribs
                                                    )
                xmlSpectrumList.__enter__()
                xmlWriter.write('\n')

                for index, key in enumerate(spectrumIds):
                    smi = msrunContainer.smic[specfile][key]
                    sai = msrunContainer.saic[specfile][key]
                    #Store the spectrum element offset here
                    spectrumIndexList.append((outputFile.tell(),
                                              smi.attributes['id']
                                              ))

                    xmlSpectrum = xmlSpectrumFromSmi(index, smi, sai)
                    xmlWriter.write(xmlSpectrum, pretty_print=True)

                xmlSpectrumList.__exit__(None, None, None)
                xmlWriter.write('\n')

            #If any chromatograms should be written, generate the
            #chromatogramList Node.
            if chromatogramCounts > 0:
                chromListAttribs = {'count': str(chromatogramCounts),
                                    'defaultDataProcessingRef': chromDefaultProcRef
                                    }
                xmlChromatogramList = xmlWriter.element('chromatogramList',
                                                        chromListAttribs
                                                        )
                xmlChromatogramList.__enter__()
                xmlWriter.write('\n')
                for index, key in enumerate(chromatogramIds):
                    ci = msrunContainer.cic[specfile][key]
                    #Store the chromatogram element offset here
                    chromatogramIndexList.append((outputFile.tell(), ci.id))

                    xmlChromatogram = xmlChromatogramFromCi(index, ci)
                    xmlWriter.write(xmlChromatogram, pretty_print=True)
                xmlChromatogramList.__exit__(None, None, None)
                xmlWriter.write('\n')

            xmlRun.__exit__(None, None, None)
            xmlWriter.write('\n')

    #Close the mzml node
    xmlMzml.__exit__(None, None, None)
    #Optional: write the indexedMzml nodes and close the indexedMzml node
    if writeIndex:
        xmlWriter.write('\n')
        indexListOffset = outputFile.tell()
        _writeMzmlIndexList(xmlWriter, spectrumIndexList, chromatogramIndexList)
        _writeIndexListOffset(xmlWriter, indexListOffset)
        _writeMzmlChecksum(xmlWriter, outputFile)
        xmlIndexedMzml.__exit__(None, None, None)
    #Close the xml file
    xmlFile.__exit__(None, None, None)
    #Write the output mzML file
    filepath = aux.joinpath(outputdir, specfile+'.mzML')
    with open(filepath, 'wb') as openfile:
        openfile.write(outputFile.getvalue())