void addCollection() {
    Type type = propertyValue.getType();
    Value value = propertyValue.getElement();

    boolean oneToManyAttachedType =
        type instanceof BagType
            || type instanceof SetType
            || type instanceof MapType
            || type instanceof ListType;
    boolean inverseOneToMany = (value instanceof OneToMany) && (propertyValue.isInverse());
    boolean owningManyToOneWithJoinTableBidirectional =
        (value instanceof ManyToOne) && (propertyAuditingData.getAuditMappedBy() != null);
    boolean fakeOneToManyBidirectional =
        (value instanceof OneToMany) && (propertyAuditingData.getAuditMappedBy() != null);

    if (oneToManyAttachedType
        && (inverseOneToMany
            || fakeOneToManyBidirectional
            || owningManyToOneWithJoinTableBidirectional)) {
      // A one-to-many relation mapped using @ManyToOne and @OneToMany(mappedBy="...")
      addOneToManyAttached(fakeOneToManyBidirectional);
    } else {
      // All other kinds of relations require a middle (join) table.
      addWithMiddleTable();
    }
  }
 private void addMapper(
     CommonCollectionMapperData commonCollectionMapperData,
     MiddleComponentData elementComponentData,
     MiddleComponentData indexComponentData) {
   Type type = propertyValue.getType();
   if (type instanceof SortedSetType) {
     currentMapper.addComposite(
         propertyAuditingData.getPropertyData(),
         new SortedSetCollectionMapper(
             commonCollectionMapperData,
             TreeSet.class,
             SortedSetProxy.class,
             elementComponentData,
             propertyValue.getComparator()));
   } else if (type instanceof SetType) {
     currentMapper.addComposite(
         propertyAuditingData.getPropertyData(),
         new BasicCollectionMapper<Set>(
             commonCollectionMapperData, HashSet.class, SetProxy.class, elementComponentData));
   } else if (type instanceof SortedMapType) {
     // Indexed collection, so <code>indexComponentData</code> is not null.
     currentMapper.addComposite(
         propertyAuditingData.getPropertyData(),
         new SortedMapCollectionMapper(
             commonCollectionMapperData,
             TreeMap.class,
             SortedMapProxy.class,
             elementComponentData,
             indexComponentData,
             propertyValue.getComparator()));
   } else if (type instanceof MapType) {
     // Indexed collection, so <code>indexComponentData</code> is not null.
     currentMapper.addComposite(
         propertyAuditingData.getPropertyData(),
         new MapCollectionMapper<Map>(
             commonCollectionMapperData,
             HashMap.class,
             MapProxy.class,
             elementComponentData,
             indexComponentData));
   } else if (type instanceof BagType) {
     currentMapper.addComposite(
         propertyAuditingData.getPropertyData(),
         new BasicCollectionMapper<List>(
             commonCollectionMapperData, ArrayList.class, ListProxy.class, elementComponentData));
   } else if (type instanceof ListType) {
     // Indexed collection, so <code>indexComponentData</code> is not null.
     currentMapper.addComposite(
         propertyAuditingData.getPropertyData(),
         new ListCollectionMapper(
             commonCollectionMapperData, elementComponentData, indexComponentData));
   } else {
     mainGenerator.throwUnsupportedTypeException(type, referencingEntityName, propertyName);
   }
 }