docs: public void process() throws ConstraintException
      {
          ClassDescriptorDef otherClassDef;
          
          for (Iterator it = getDirectBaseTypes(); it.hasNext();)
          {
              otherClassDef = (ClassDescriptorDef)it.next();
              if (!otherClassDef.hasBeenProcessed())
              {
                  otherClassDef.process();
              }
          }
          for (Iterator it = getNested(); it.hasNext();)
          {
              otherClassDef = ((NestedDef)it.next()).getNestedType();
              if (!otherClassDef.hasBeenProcessed())
              {
                  otherClassDef.process();
              }
          }
          
          ArrayList               newFields      = new ArrayList();
          ArrayList               newReferences  = new ArrayList();
          ArrayList               newCollections = new ArrayList();
          FieldDescriptorDef      newFieldDef;
          ReferenceDescriptorDef  newRefDef;
          CollectionDescriptorDef newCollDef;
          
          // adding base features
          if (getBooleanProperty(PropertyHelper.OJB_PROPERTY_INCLUDE_INHERITED, true))
          {
              ArrayList baseTypes = new ArrayList();
              DefBase   featureDef;
              
              addRelevantBaseTypes(this, baseTypes);
              for (Iterator it = baseTypes.iterator(); it.hasNext();)
              {
                  cloneInheritedFeatures((ClassDescriptorDef)it.next(), newFields, newReferences, newCollections);
              }
  
              for (Iterator it = newFields.iterator(); it.hasNext();)
              {
                  newFieldDef = (FieldDescriptorDef)it.next();
                  featureDef  = getFeature(newFieldDef.getName());
                  if (featureDef != null)
                  {    
                      if (!getBooleanProperty(PropertyHelper.OJB_PROPERTY_IGNORE, false))
                      {
                          // we have the implicit constraint that an anonymous field cannot redefine/be redefined
                          // except if it is ignored
                          if ("anonymous".equals(featureDef.getProperty(PropertyHelper.OJB_PROPERTY_ACCESS)))
                          {
                              throw new ConstraintException("The anonymous field "+featureDef.getName()+" in class "+getName()+" overrides an inherited field");
                          }
                          if ("anonymous".equals(newFieldDef.getProperty(PropertyHelper.OJB_PROPERTY_ACCESS)))
                          {
                              throw new ConstraintException("The inherited anonymous field "+newFieldDef.getName()+" is overriden in class "+getName());
                          }
                      }
                      LogHelper.warn(true, ClassDescriptorDef.class, "process", "Class "+getName()+" redefines the inherited field "+newFieldDef.getName());
                      it.remove();
                  }
              }
              for (Iterator it = newReferences.iterator(); it.hasNext();)
              {
                  newRefDef = (ReferenceDescriptorDef)it.next();
                  if ("super".equals(newRefDef.getName()))
                  {
                      // we don't inherit super-references
                      it.remove();
                  }
                  else if (hasFeature(newRefDef.getName()))
                  {
                      LogHelper.warn(true, ClassDescriptorDef.class, "process", "Class "+getName()+" redefines the inherited reference "+newRefDef.getName());
                      it.remove();
                  }
              }
              for (Iterator it = newCollections.iterator(); it.hasNext();)
              {
                  newCollDef = (CollectionDescriptorDef)it.next();
                  if (hasFeature(newCollDef.getName()))
                  {
                      LogHelper.warn(true, ClassDescriptorDef.class, "process", "Class "+getName()+" redefines the inherited collection "+newCollDef.getName());
                      it.remove();
                  }
              }
          }
          // adding nested features
          for (Iterator it = getNested(); it.hasNext();)
          {
              cloneNestedFeatures((NestedDef)it.next(), newFields, newReferences, newCollections);
          }
          _fields.addAll(0, newFields);
          _references.addAll(0, newReferences);
          _collections.addAll(0, newCollections);
          sortFields();
          _hasBeenProcessed = true;
      }