/**
   * reflect the bean properties from Class. Some of these properties may not map to database
   * columns.
   */
  private void createProperties(DeployBeanDescriptor<?> desc, Class<?> beanType, int level) {

    boolean scalaObject = desc.isScalaObject();

    try {
      Method[] declaredMethods = beanType.getDeclaredMethods();
      Field[] fields = beanType.getDeclaredFields();

      for (int i = 0; i < fields.length; i++) {

        Field field = fields[i];
        if (Modifier.isStatic(field.getModifiers())) {
          // not interested in static fields

        } else if (Modifier.isTransient(field.getModifiers())) {
          // not interested in transient fields
          logger.finer("Skipping transient field " + field.getName() + " in " + beanType.getName());

        } else if (ignoreFieldByName(field.getName())) {
          // not interested this field (ebean or aspectJ field)

        } else {

          String fieldName = getFieldName(field, beanType);
          String initFieldName = initCap(fieldName);

          Method getter = findGetter(field, initFieldName, declaredMethods, scalaObject);
          Method setter = findSetter(field, initFieldName, declaredMethods, scalaObject);

          DeployBeanProperty prop = createProp(level, desc, field, beanType, getter, setter);
          if (prop == null) {
            // transient annotation on unsupported type

          } else {
            // set a order that gives priority to inherited properties
            // push Id/EmbeddedId up and CreatedTimestamp/UpdatedTimestamp down
            int sortOverride = prop.getSortOverride();
            prop.setSortOrder((level * 10000 + 100 - i + sortOverride));

            DeployBeanProperty replaced = desc.addBeanProperty(prop);
            if (replaced != null) {
              if (replaced.isTransient()) {
                // expected for inheritance...
              } else {
                String msg = "Huh??? property " + prop.getFullBeanName() + " being defined twice";
                msg += " but replaced property was not transient? This is not expected?";
                logger.warning(msg);
              }
            }
          }
        }
      }

      Class<?> superClass = beanType.getSuperclass();

      if (!superClass.equals(Object.class)) {
        // recursively add any properties in the inheritance heirarchy
        // up to the Object.class level...
        createProperties(desc, superClass, level + 1);
      }

    } catch (PersistenceException ex) {
      throw ex;

    } catch (Exception ex) {
      throw new PersistenceException(ex);
    }
  }