/** Introspects. */
  public BeanType introspect(Class type) throws ConfigException, SQLException {
    BeanType beanType = null;

    try {
      EntityType entityType = null;

      EntityType parentType = introspectParent(type.getSuperclass());

      entityType = introspectEntityType(type, parentType);

      if (entityType == null) entityType = introspectMappedType(type, parentType);

      if (entityType == null) return introspectEmbeddableType(type);

      beanType = entityType;

      // jpa/0ge2
      entityType.setInstanceClassName(type.getName() + "__ResinExt");
      entityType.setEnhanced(true);

      MappedSuperclassConfig mappedSuperOrEntityConfig = introspectEntityConfig(type);

      entityType.setParentType(parentType);

      introspectTable(type, entityType, parentType);

      // inheritance must be after table since it adds columns
      introspectInheritance(type, entityType, parentType);

      introspectTableCache(entityType, type);

      getInternalIdClassConfig(type, _annotationCfg);
      IdClass idClassAnn = (IdClass) _annotationCfg.getAnnotation();
      IdClassConfig idClassConfig = _annotationCfg.getIdClassConfig();

      Class idClass = null;
      if (!_annotationCfg.isNull()) {
        if (idClassAnn != null) idClass = idClassAnn.value();
        else {
          String s = idClassConfig.getClassName();
          idClass = _persistenceUnit.loadTempClass(s);
        }

        // XXX: temp. introspects idClass as an embeddable type.
        _persistenceUnit.addEntityClass(idClass.getName(), idClass);

        // jpa/0i49 vs jpa/0i40
        // embeddable.setFieldAccess(isField);
      }

      if (entityType.getId() != null) {
      } else if (entityType.isFieldAccess())
        introspectIdField(
            _persistenceUnit, entityType, parentType, type, idClass, mappedSuperOrEntityConfig);
      else {
        introspectIdMethod(
            _persistenceUnit, entityType, parentType, type, idClass, mappedSuperOrEntityConfig);
      }

      HashMap<String, IdConfig> idMap = null;

      AttributesConfig attributes = null;

      if (mappedSuperOrEntityConfig != null) {
        attributes = mappedSuperOrEntityConfig.getAttributes();

        if (attributes != null) idMap = attributes.getIdMap();
      }

      // if ((idMap == null) || (idMap.size() == 0)) {
      //   idMap = entityType.getSuperClass();
      // }

      if (entityType.isEntity()
          && (entityType.getId() == null)
          && ((idMap == null) || (idMap.size() == 0)))
        throw new ConfigException(
            L.l(
                "{0} does not have any primary keys.  Entities must have at least one @Id or exactly one @EmbeddedId field.",
                entityType.getName()));

      // Introspect overridden attributes. (jpa/0ge2)
      introspectAttributeOverrides(entityType, type);

      introspectSecondaryTable(entityType, type);

      if (entityType.isFieldAccess())
        introspectFields(
            _persistenceUnit, entityType, parentType, type, mappedSuperOrEntityConfig, false);
      else
        introspectMethods(
            _persistenceUnit, entityType, parentType, type, mappedSuperOrEntityConfig);

      introspectCallbacks(type, entityType);

      // Adds entity listeners, if any.
      introspectEntityListeners(type, entityType, _persistenceUnit);

      // Adds sql result set mappings, if any.
      introspectSqlResultSetMappings(type, entityType, entityType.getName());

      // Adds named queries, if any.
      introspectNamedQueries(type, entityType.getName());
      introspectNamedNativeQueries(type, entityType.getName());
    } catch (ConfigException e) {
      if (beanType != null) beanType.setConfigException(e);

      throw e;
    } catch (SQLException e) {
      if (beanType != null) beanType.setConfigException(e);

      throw e;
    } catch (RuntimeException e) {
      if (beanType != null) beanType.setConfigException(e);

      throw e;
    }

    return beanType;
  }
  private EntityType introspectMappedType(Class type, EntityType parentType) throws SQLException {
    EntityType entityType;

    boolean isMappedSuperclass = false;
    MappedSuperclass mappedSuperAnn = null;
    MappedSuperclassConfig mappedSuperConfig = null;

    String typeName;

    MappedSuperclassConfig mappedSuperOrEntityConfig = null;

    getInternalMappedSuperclassConfig(type, _annotationCfg);
    mappedSuperAnn = (MappedSuperclass) _annotationCfg.getAnnotation();
    mappedSuperConfig = _annotationCfg.getMappedSuperclassConfig();

    isMappedSuperclass = !_annotationCfg.isNull();

    if (!isMappedSuperclass) return null;

    mappedSuperOrEntityConfig = mappedSuperConfig;

    if (mappedSuperConfig != null) typeName = mappedSuperConfig.getClassName();
    /*    else
          typeName = mappedSuperAnn.name();
    */
    // Validates the type
    String entityName;
    Inheritance inheritanceAnn = null;
    InheritanceConfig inheritanceConfig = null;
    Class rootClass = type;
    Entity rootEntityAnn = null;
    EntityConfig rootEntityConfig = null;

    validateType(type, false);

    // jpa/0ge2
    // if (hasInheritance) {

    if (mappedSuperConfig == null) entityName = null; // mappedSuperAnn.name();
    else {
      entityName = mappedSuperConfig.getSimpleClassName();
    }

    if ((entityName == null) || "".equals(entityName)) {
      entityName = type.getSimpleName();
    }

    entityType = _persistenceUnit.createMappedSuperclass(entityName, type);

    _configManager.addType(type, new EntityConfig(type.getName(), this, entityType));

    boolean isField = isField(type, mappedSuperOrEntityConfig, false);

    if (isField) entityType.setFieldAccess(true);

    // jpa/0ge2
    entityType.setInstanceClassName(type.getName() + "__ResinExt");
    entityType.setEnhanced(true);

    return entityType;
  }