class DetailViewMapping(schema.Annotation): """ A mapping between a Kind and the detail view (actually, its rows of blocks) that should appear when an Item inheriting from that Kind is displayed. """ schema.kindInfo(annotates=schema.Kind) detailRows = schema.Sequence(inverse=DetailRow.detailViewMapping) class DetailRow(schema.Item): """ One horizontal slice of the detail view """ detailViewMapping = schema.One() # DetailViewMapping.detailRows position = schema.One(schema.Float) blocks = schema.Sequence(inverse=DetailBlock.detailRow) [...] class DetailBlock(schema.Annotation): """ A block in the detail view - we annotate it with the row it belongs to """ schema.kindInfo(annotates=Block.Block) detailRow = schema.One() # detailRow.blocks schema.addClouds( copying = schema.Cloud( byRef = [detailRow] ) ) Building a detail view for an item - collect the DetailViewMappings that exist for any of the item's kinds - make a decorated list of the DetailRows belonging to those mappings; sort it by position - copy a stub block that'll be the root of the new detail view - copy each of the blocks in the DetailRows list onto the stub copy's childBlocks list. As specified above, DetailBlock.detailRow is copied byRef, which means that each time I copy a row's blocks, extra copies of blocks get added to the detailRow.blocks list :-( If I copy the detailRow too, then I'll get an extra detailRow copy per block, bad (and the DetailViewMapping.detailRows list will get extra blocks.