/** 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;
  }