'Writes the collection of pages added to this object out as a PDF file.
:param stream: An object to write the file to.  The object must support
the write method and the tell method, similar to a file object.'

def write(self, stream):

    if (hasattr(stream, 'mode') and ('b' not in stream.mode)):
        warnings.warn(('File    <%s>    to    write    to    is    not    in    binary    mode.    It    may    not    be    written    to    correctly.' % stream.name))
    debug = False
    import struct
    if (not self._root):
        self._root = self._addObject(self._root_object)
    externalReferenceMap = {}
    for objIndex in range(len(self._objects)):
        obj = self._objects[objIndex]
        if (isinstance(obj, PageObject) and (obj.indirectRef != None)):
            data = obj.indirectRef
            if (data.pdf not in externalReferenceMap):
                externalReferenceMap[data.pdf] = {}
            if (data.generation not in externalReferenceMap[data.pdf]):
                externalReferenceMap[data.pdf][data.generation] = {}
            externalReferenceMap[data.pdf][data.generation][data.idnum] = IndirectObject((objIndex + 1), 0, self)
    self.stack = []
    if debug:
        print ('ERM:', externalReferenceMap, 'root:', self._root)
    self._sweepIndirectReferences(externalReferenceMap, self._root)
    del self.stack
    object_positions = []
    stream.write((self._header + b_('\n')))
    for i in range(len(self._objects)):
        idnum = (i + 1)
        obj = self._objects[i]
        object_positions.append(stream.tell())
        stream.write(b_((str(idnum) + '    0    obj\n')))
        key = None
        if (hasattr(self, '_encrypt') and (idnum != self._encrypt.idnum)):
            pack1 = struct.pack('<i', (i + 1))[:3]
            pack2 = struct.pack('<i', 0)[:2]
            key = ((self._encrypt_key + pack1) + pack2)
            assert (len(key) == (len(self._encrypt_key) + 5))
            md5_hash = md5(key).digest()
            key = md5_hash[:min(16, (len(self._encrypt_key) + 5))]
        obj.writeToStream(stream, key)
        stream.write(b_('\nendobj\n'))
    xref_location = stream.tell()
    stream.write(b_('xref\n'))
    stream.write(b_(('0    %s\n' % (len(self._objects) + 1))))
    stream.write(b_(('%010d    %05d    f    \n' % (0, 65535))))
    for offset in object_positions:
        stream.write(b_(('%010d    %05d    n    \n' % (offset, 0))))
    stream.write(b_('trailer\n'))
    trailer = DictionaryObject()
    trailer.update({NameObject('/Size'): NumberObject((len(self._objects) + 1)), NameObject('/Root'): self._root, NameObject('/Info'): self._info})
    if hasattr(self, '_ID'):
        trailer[NameObject('/ID')] = self._ID
    if hasattr(self, '_encrypt'):
        trailer[NameObject('/Encrypt')] = self._encrypt
    trailer.writeToStream(stream, None)
    stream.write(b_(('\nstartxref\n%s\n%%%%EOF\n' % xref_location)))
