/**
  * Generates the prefixes for the specified topic (incl. its played roles and occurrences and
  * names).
  *
  * @param topic The topic to generate the prefixes for.
  */
 private void _registerPrefixes(final Topic topic) {
   _generateTopicReferences(topic.getTypes());
   for (Occurrence occ : topic.getOccurrences()) {
     _generatePrefixes(occ);
   }
   for (Name name : topic.getNames()) {
     _generatePrefixes(name);
     for (Variant variant : name.getVariants()) {
       _generatePrefixes(variant);
     }
   }
   for (Role rolePlayed : topic.getRolesPlayed()) {
     Association assoc = rolePlayed.getParent();
     _generatePrefixes(assoc);
     for (Role role : assoc.getRoles()) {
       _getTopicReference(role.getType());
     }
   }
 }
  /**
   * Writes the specified topic.
   *
   * @param topic The topic to serialize.
   * @throws IOException In case of an error.
   */
  private void _writeTopic(final Topic topic) throws IOException {
    final String[] types = _getTypes(topic);
    final String[] sids = _getSubjectIdentifiers(topic);
    final String[] slos = _getSubjectLocators(topic);
    if (topic.getSubjectIdentifiers().contains(_defaultNameTypeLocator)
        && sids.length == 1
        && slos.length == 0
        && topic.getRolesPlayed().isEmpty()
        && topic.getOccurrences().isEmpty()
        && topic.getNames().isEmpty()
        && types.length == 0) {
      return;
    }
    final String element = types.length > 0 ? types[0] : _UNTYPED_TOPIC;
    // Only add id iff no sids and slos are available
    if (sids.length == 0 && slos.length == 0) {
      _attrs.clear();
      super.addAttribute("id", super.getId(topic));
      _out.startElement(element, _attrs);
    } else {
      final String id = _getTopicIdentifier(topic);
      if (id != null) {
        _attrs.clear();
        super.addAttribute("id", id);
        _out.startElement(element, _attrs);
      } else {
        _out.startElement(element);
      }
    }
    for (String sid : sids) {
      _out.dataElement(_EL_SID, sid);
    }
    for (String slo : slos) {
      _out.dataElement(_EL_SLO, slo);
    }
    for (Name name : topic.getNames()) {
      _writeName(name);
    }
    for (Occurrence occ : topic.getOccurrences()) {
      _writeOccurrence(occ);
    }
    // Type-instance relationships
    for (int i = 1; i < types.length; i++) {
      _attrs.clear();
      super.addAttribute("role", _INSTANCE);
      super.addAttribute("otherrole", _TYPE);
      super.addAttribute("topicref", types[i]);
      _out.emptyElement(_TYPE_INSTANCE, _attrs);
    }
    for (Role playedRole : topic.getRolesPlayed()) {
      final Association assoc = playedRole.getParent();
      if (_exportedAssocIds.contains(assoc.getId())
          || super.isTypeInstanceAssociation(assoc, assoc.getRoles())) {
        continue;
      }
      _exportedAssocIds.add(assoc.getId());
      _attrs.clear();
      _addScopeAndReifier(assoc);
      _addToAttributes("role", playedRole.getType());
      final String assocElement = _type(assoc);
      final int arity = assoc.getRoles().size();
      if (arity == 1) {
        _out.emptyElement(assocElement, _attrs);
      } else if (arity == 2) {
        for (Role role : assoc.getRoles()) {
          if (!role.equals(playedRole)) {
            _addToAttributes("topicref", role.getPlayer());
            _addToAttributes("otherrole", role.getType());
          }
        }
        _out.emptyElement(assocElement, _attrs);
      } else {
        // n-ary association
        _out.startElement(assocElement, _attrs);
        for (Role role : assoc.getRoles()) {
          if (role.equals(playedRole)) {
            continue;
          }
          _attrs.clear();
          _addToAttributes("topicref", role.getPlayer());
          _out.emptyElement(_type(role), _attrs);
        }

        _out.endElement(assocElement);
      }
    }
    _out.endElement(element);
  }