private Element createMiddleEntityXml(
      String auditMiddleTableName, String auditMiddleEntityName, String where) {
    String schema =
        mainGenerator.getSchema(
            propertyAuditingData.getJoinTable().schema(), propertyValue.getCollectionTable());
    String catalog =
        mainGenerator.getCatalog(
            propertyAuditingData.getJoinTable().catalog(), propertyValue.getCollectionTable());

    Element middleEntityXml =
        MetadataTools.createEntity(
            xmlMappingData.newAdditionalMapping(),
            new AuditTableData(auditMiddleEntityName, auditMiddleTableName, schema, catalog),
            null);
    Element middleEntityXmlId = middleEntityXml.addElement("composite-id");

    // If there is a where clause on the relation, adding it to the middle entity.
    if (where != null) {
      middleEntityXml.addAttribute("where", where);
    }

    middleEntityXmlId.addAttribute("name", mainGenerator.getVerEntCfg().getOriginalIdPropName());

    // Adding the revision number as a foreign key to the revision info entity to the composite id
    // of the
    // middle table.
    mainGenerator.addRevisionInfoRelation(middleEntityXmlId);

    // Adding the revision type property to the entity xml.
    mainGenerator.addRevisionType(middleEntityXml);

    // All other properties should also be part of the primary key of the middle entity.
    return middleEntityXmlId;
  }
  @SuppressWarnings({"unchecked"})
  IdMappingData addId(PersistentClass pc, boolean audited) {
    // Xml mapping which will be used for relations
    Element rel_id_mapping = new DefaultElement("properties");
    // Xml mapping which will be used for the primary key of the versions table
    Element orig_id_mapping = new DefaultElement("composite-id");

    Property id_prop = pc.getIdentifierProperty();
    Component id_mapper = pc.getIdentifierMapper();

    // Checking if the id mapping is supported
    if (id_mapper == null && id_prop == null) {
      return null;
    }

    SimpleIdMapperBuilder mapper;
    if (id_mapper != null) {
      // Multiple id

      mapper = new MultipleIdMapper(((Component) pc.getIdentifier()).getComponentClassName());
      if (!addIdProperties(
          rel_id_mapping,
          (Iterator<Property>) id_mapper.getPropertyIterator(),
          mapper,
          false,
          audited)) {
        return null;
      }

      // null mapper - the mapping where already added the first time, now we only want to generate
      // the xml
      if (!addIdProperties(
          orig_id_mapping,
          (Iterator<Property>) id_mapper.getPropertyIterator(),
          null,
          true,
          audited)) {
        return null;
      }
    } else if (id_prop.isComposite()) {
      // Embedded id

      Component id_component = (Component) id_prop.getValue();

      mapper =
          new EmbeddedIdMapper(getIdPropertyData(id_prop), id_component.getComponentClassName());
      if (!addIdProperties(
          rel_id_mapping,
          (Iterator<Property>) id_component.getPropertyIterator(),
          mapper,
          false,
          audited)) {
        return null;
      }

      // null mapper - the mapping where already added the first time, now we only want to generate
      // the xml
      if (!addIdProperties(
          orig_id_mapping,
          (Iterator<Property>) id_component.getPropertyIterator(),
          null,
          true,
          audited)) {
        return null;
      }
    } else {
      // Single id

      mapper = new SingleIdMapper();

      // Last but one parameter: ids are always insertable
      mainGenerator
          .getBasicMetadataGenerator()
          .addBasic(
              rel_id_mapping,
              getIdPersistentPropertyAuditingData(id_prop),
              id_prop.getValue(),
              mapper,
              true,
              false);

      // null mapper - the mapping where already added the first time, now we only want to generate
      // the xml
      mainGenerator
          .getBasicMetadataGenerator()
          .addBasic(
              orig_id_mapping,
              getIdPersistentPropertyAuditingData(id_prop),
              id_prop.getValue(),
              null,
              true,
              true);
    }

    orig_id_mapping.addAttribute("name", mainGenerator.getVerEntCfg().getOriginalIdPropName());

    // Adding a relation to the revision entity (effectively: the "revision number" property)
    mainGenerator.addRevisionInfoRelation(orig_id_mapping);

    return new IdMappingData(mapper, orig_id_mapping, rel_id_mapping);
  }