/**
   * Generates the attribute representation of the identifier for a given entity mapping.
   *
   * @param mappedEntity The mapping definition of the entity.
   * @param generator The identifier value generator to use for this identifier.
   * @return The appropriate IdentifierProperty definition.
   */
  public static IdentifierProperty buildIdentifierAttribute(
      PersistentClass mappedEntity, IdentifierGenerator generator) {
    String mappedUnsavedValue = mappedEntity.getIdentifier().getNullValue();
    Type type = mappedEntity.getIdentifier().getType();
    Property property = mappedEntity.getIdentifierProperty();

    IdentifierValue unsavedValue =
        UnsavedValueFactory.getUnsavedIdentifierValue(
            mappedUnsavedValue, getGetter(property), type, getConstructor(mappedEntity));

    if (property == null) {
      // this is a virtual id property...
      return new IdentifierProperty(
          type,
          mappedEntity.hasEmbeddedIdentifier(),
          mappedEntity.hasIdentifierMapper(),
          unsavedValue,
          generator);
    } else {
      return new IdentifierProperty(
          property.getName(),
          property.getNodeName(),
          type,
          mappedEntity.hasEmbeddedIdentifier(),
          unsavedValue,
          generator);
    }
  }
  public static GroovyAwareJavassistProxyFactory buildProxyFactory(
      PersistentClass persistentClass) {
    GroovyAwareJavassistProxyFactory proxyFactory = new GroovyAwareJavassistProxyFactory();

    @SuppressWarnings("unchecked")
    Set<Class<HibernateProxy>> proxyInterfaces = new HashSet<Class<HibernateProxy>>();
    proxyInterfaces.add(HibernateProxy.class);

    final Class<?> javaClass = persistentClass.getMappedClass();
    final Property identifierProperty = persistentClass.getIdentifierProperty();
    final Method idGetterMethod =
        identifierProperty != null ? identifierProperty.getGetter(javaClass).getMethod() : null;
    final Method idSetterMethod =
        identifierProperty != null ? identifierProperty.getSetter(javaClass).getMethod() : null;
    final Type identifierType =
        persistentClass.hasEmbeddedIdentifier() ? persistentClass.getIdentifier().getType() : null;

    try {
      proxyFactory.postInstantiate(
          persistentClass.getEntityName(),
          javaClass,
          proxyInterfaces,
          idGetterMethod,
          idSetterMethod,
          identifierType instanceof CompositeType ? (CompositeType) identifierType : null);
    } catch (HibernateException e) {
      LOG.warn("Cannot instantiate proxy factory: " + e.getMessage());
      return null;
    }

    return proxyFactory;
  }
  /**
   * @param cfg
   * @param exporter
   * @param file
   */
  public void export(Configuration cfg, ConfigurationVisitor exporter) {

    Map<String, Component> components = new HashMap<String, Component>();
    Metadata md = getMetadata(cfg);

    for (Iterator<PersistentClass> classes = md.getEntityBindings().iterator();
        classes.hasNext(); ) {
      if (exporter.startMapping(cfg)) {
        PersistentClass clazz = classes.next();
        collectComponents(components, clazz);

        if (exporter.startPersistentClass(clazz)) {
          if (clazz.hasIdentifierProperty()) {
            exporter.startIdentifierProperty(clazz.getIdentifierProperty());
            exporter.endIdentifierProperty(clazz.getIdentifierProperty());
          } else if (clazz.hasEmbeddedIdentifier()) {
            exporter.startEmbeddedIdentifier((Component) clazz.getKey());
            exporter.endEmbeddedIdentifier((Component) clazz.getKey());
          }
          Iterator<?> unjoinedPropertyIterator = clazz.getUnjoinedPropertyIterator();
          while (unjoinedPropertyIterator.hasNext()) {
            Property prop = (Property) unjoinedPropertyIterator.next();
            exporter.startProperty(prop);
            exporter.endProperty(prop);
          }
        }
        exporter.endPersistentClass(clazz);
      } else {
        exporter.endMapping(cfg);
      }
    }

    for (Iterator<?> comps = components.values().iterator(); comps.hasNext(); ) {
      Component component = (Component) comps.next();
      exporter.startComponent(component);
    }

    if (exporter.startGeneralConfiguration(cfg)) exporter.endGeneralConfiguration(cfg);
  }