'Strategy is:
- write header
- wrap root object so everything is hashable
- compute size of objects which will be written
- need to do this in order to know how large the object refs
will be in the list/dict/set reference lists
- write objects
- keep objects in writtenReferences
- keep positions of object references in referencePositions
- write object references with the length computed previously
- computer object reference length
- write object reference positions
- write trailer'

def writeRoot(self, root):

    output = self.header
    wrapped_root = self.wrapRoot(root)
    should_reference_root = True
    self.computeOffsets(wrapped_root, asReference=should_reference_root, isRoot=True)
    self.trailer = self.trailer._replace(**{'objectRefSize': self.intSize(len(self.computedUniques))})
    (_, output) = self.writeObjectReference(wrapped_root, output)
    output = self.writeObject(wrapped_root, output, setReferencePosition=True)
    self.trailer = self.trailer._replace(**{'offsetSize': self.intSize(len(output)), 'offsetCount': len(self.computedUniques), 'offsetTableOffset': len(output), 'topLevelObjectNumber': 0})
    output = self.writeOffsetTable(output)
    output += pack('!xxxxxxBBQQQ', *self.trailer)
    self.file.write(output)
