private void collectTypes()
      throws IOException, XMLStreamException, ClassNotFoundException, SecurityException,
          NoSuchMethodException {
    // super classes
    Iterator<?> superClassMappings = configuration.getMappedSuperclassMappings();
    while (superClassMappings.hasNext()) {
      MappedSuperclass msc = (MappedSuperclass) superClassMappings.next();
      EntityType entityType = createSuperType(msc.getMappedClass());
      if (msc.getDeclaredIdentifierProperty() != null) {
        handleProperty(entityType, msc.getMappedClass(), msc.getDeclaredIdentifierProperty());
      }
      Iterator<?> properties = msc.getDeclaredPropertyIterator();
      while (properties.hasNext()) {
        handleProperty(
            entityType, msc.getMappedClass(), (org.hibernate.mapping.Property) properties.next());
      }
    }

    // entity classes
    Iterator<?> classMappings = configuration.getClassMappings();
    while (classMappings.hasNext()) {
      PersistentClass pc = (PersistentClass) classMappings.next();
      EntityType entityType = createEntityType(pc.getMappedClass());
      if (pc.getDeclaredIdentifierProperty() != null) {
        handleProperty(entityType, pc.getMappedClass(), pc.getDeclaredIdentifierProperty());
      } else if (!pc.isInherited() && pc.hasIdentifierProperty()) {
        logger.info(entityType.toString() + pc.getIdentifierProperty());
        handleProperty(entityType, pc.getMappedClass(), pc.getIdentifierProperty());
      }
      Iterator<?> properties = pc.getDeclaredPropertyIterator();
      while (properties.hasNext()) {
        handleProperty(
            entityType, pc.getMappedClass(), (org.hibernate.mapping.Property) properties.next());
      }
    }
  }
  @SuppressWarnings({"unchecked"})
  public void wrapUp() {
    LOG.trace("Wrapping up metadata context...");

    // we need to process types from superclasses to subclasses
    for (Object mapping : orderedMappings) {
      if (PersistentClass.class.isAssignableFrom(mapping.getClass())) {
        @SuppressWarnings("unchecked")
        final PersistentClass safeMapping = (PersistentClass) mapping;
        LOG.trace("Starting entity [" + safeMapping.getEntityName() + "]");
        try {
          final EntityTypeImpl<?> jpa2Mapping = entityTypesByPersistentClass.get(safeMapping);
          applyIdMetadata(safeMapping, jpa2Mapping);
          applyVersionAttribute(safeMapping, jpa2Mapping);
          Iterator<Property> properties = safeMapping.getDeclaredPropertyIterator();
          while (properties.hasNext()) {
            final Property property = properties.next();
            if (property.getValue() == safeMapping.getIdentifierMapper()) {
              // property represents special handling for id-class mappings but we have already
              // accounted for the embedded property mappings in #applyIdMetadata &&
              // #buildIdClassAttributes
              continue;
            }
            if (safeMapping.isVersioned() && property == safeMapping.getVersion()) {
              // skip the version property, it was already handled previously.
              continue;
            }
            final Attribute attribute = attributeFactory.buildAttribute(jpa2Mapping, property);
            if (attribute != null) {
              jpa2Mapping.getBuilder().addAttribute(attribute);
            }
          }
          jpa2Mapping.lock();
          populateStaticMetamodel(jpa2Mapping);
        } finally {
          LOG.trace("Completed entity [" + safeMapping.getEntityName() + "]");
        }
      } else if (MappedSuperclass.class.isAssignableFrom(mapping.getClass())) {
        @SuppressWarnings("unchecked")
        final MappedSuperclass safeMapping = (MappedSuperclass) mapping;
        LOG.trace("Starting mapped superclass [" + safeMapping.getMappedClass().getName() + "]");
        try {
          final MappedSuperclassTypeImpl<?> jpa2Mapping =
              mappedSuperclassByMappedSuperclassMapping.get(safeMapping);
          applyIdMetadata(safeMapping, jpa2Mapping);
          applyVersionAttribute(safeMapping, jpa2Mapping);
          Iterator<Property> properties = safeMapping.getDeclaredPropertyIterator();
          while (properties.hasNext()) {
            final Property property = properties.next();
            if (safeMapping.isVersioned() && property == safeMapping.getVersion()) {
              // skip the version property, it was already handled previously.
              continue;
            }
            final Attribute attribute = attributeFactory.buildAttribute(jpa2Mapping, property);
            if (attribute != null) {
              jpa2Mapping.getBuilder().addAttribute(attribute);
            }
          }
          jpa2Mapping.lock();
          populateStaticMetamodel(jpa2Mapping);
        } finally {
          LOG.trace("Completed mapped superclass [" + safeMapping.getMappedClass().getName() + "]");
        }
      } else {
        throw new AssertionFailure("Unexpected mapping type: " + mapping.getClass());
      }
    }

    for (EmbeddableTypeImpl embeddable : embeddables.values()) {
      populateStaticMetamodel(embeddable);
    }
  }