def class_associations(self, cn: ClassDefinitionName, must_render: bool=False) -> str:
        """ Emit all associations for a focus class.  If none are specified, all classes are generated

        @param cn: Name of class to be emitted
        @param must_render: True means render even if this is a target (class is specifically requested)
        @return: YUML representation of the association
        """

        # NOTE: YUML diagrams draw in the opposite order in which they are created, so we work from bottom to top and
        # from right to left
        assocs: List[str] = []
        if cn not in self.associations_generated and (not self.focus_classes or cn in self.focus_classes):
            cls = self.schema.classes[cn]

            # Slots
            for slotname in self.filtered_cls_slots(cn, False)[::-1]:
                slot = self.schema.slots[slotname]
                if slot.range in self.schema.classes:
                    assocs.append(self.class_box(cn) + (yuml_inline if slot.inlined else yuml_ref) +
                                  self.aliased_slot_name(slot) + self.prop_modifier(cls, slot) +
                                  self.cardinality(slot) + '>' + self.class_box(slot.range))

            # Referencing slots
            if cn in self.synopsis.rangerefs:
                for slotname in sorted(self.synopsis.rangerefs[cn]):
                    slot = self.schema.slots[slotname]
                    if slot.domain in self.schema.classes and (slot.range != cls.name or must_render):
                        assocs.append(self.class_box(slot.domain) + (yuml_inline if slot.inlined else yuml_ref) +
                                      self.aliased_slot_name(slot) + self.prop_modifier(cls, slot) +
                                      self.cardinality(slot) + '>' + self.class_box(cn))

            # Mixins used in the class
            for mixin in cls.mixins:
                assocs.append(self.class_box(cn) + yuml_uses + self.class_box(mixin))

            # Classes that use the class as a mixin
            if cls.name in self.synopsis.mixinrefs:
                for mixin in sorted(self.synopsis.mixinrefs[cls.name].classrefs, reverse=True):
                    assocs.append(self.class_box(ClassDefinitionName(mixin)) + yuml_uses + self.class_box(cn))

            # Classes that inject information
            if cn in self.synopsis.applytos:
                for injector in sorted(self.synopsis.applytos[cn].classrefs, reverse=True):
                    assocs.append(self.class_box(cn) + yuml_injected + self.class_box(ClassDefinitionName(injector)))
            self.associations_generated.add(cn)

            # Children
            if cn in self.synopsis.isarefs:
                for is_a_cls in sorted(self.synopsis.isarefs[cn].classrefs, reverse=True):
                    assocs.append(self.class_box(cn) + yuml_is_a + self.class_box(ClassDefinitionName(is_a_cls)))

            # Parent
            if cls.is_a:
                assocs.append(self.class_box(cls.is_a) + yuml_is_a + self.class_box(cn))
        return ', '.join(assocs)
Emit all associations for a focus class.  If none are specified, all classes are generated

        @param cn: Name of class to be emitted
        @param must_render: True means render even if this is a target (class is specifically requested)
        @return: YUML representation of the association