docs: private void checkCollectionForeignkeys(ModelDef modelDef, CollectionDescriptorDef collDef) throws ConstraintException
      {
          String foreignkey = collDef.getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY);
  
          if ((foreignkey == null) || (foreignkey.length() == 0))
          {
              throw new ConstraintException("The collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" has no foreignkeys");
          }
  
          String remoteForeignkey = collDef.getProperty(PropertyHelper.OJB_PROPERTY_REMOTE_FOREIGNKEY);
  
          if ((remoteForeignkey != null) && (remoteForeignkey.length() > 0))
          {
              // warning because a remote-foreignkey was specified for a 1:n collection (issue OJB-67)
              LogHelper.warn(true,
                             getClass(),
                             "checkCollectionForeignkeys",
                             "For the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+", a remote foreignkey was specified though it is a 1:n, not a m:n collection");
          }
          
          ClassDescriptorDef ownerClass       = (ClassDescriptorDef)collDef.getOwner();
          ArrayList          primFields       = ownerClass.getPrimaryKeys();
          String             elementClassName = collDef.getProperty(PropertyHelper.OJB_PROPERTY_ELEMENT_CLASS_REF);
          ArrayList          queue            = new ArrayList();
          ClassDescriptorDef elementClass;
          ArrayList          keyFields;
          FieldDescriptorDef keyField;
          FieldDescriptorDef primField;
          String             primType;
          String             keyType;
          
          // we know that the class is present because the collection constraints have been checked already
          queue.add(modelDef.getClass(elementClassName));
          while (!queue.isEmpty())
          {
              elementClass = (ClassDescriptorDef)queue.get(0);
              queue.remove(0);
  
              for (Iterator it = elementClass.getExtentClasses(); it.hasNext();)
              {
                  queue.add(it.next());
              }
              if (!elementClass.getBooleanProperty(PropertyHelper.OJB_PROPERTY_GENERATE_REPOSITORY_INFO, true))
              {
                  continue;
              }
              try
              {
                  keyFields = elementClass.getFields(foreignkey);
              }
              catch (NoSuchFieldException ex)
              {
                  throw new ConstraintException("The collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" specifies a foreignkey "+ex.getMessage()+" that is not a persistent field in the element class (or its subclass) "+elementClass.getName());
              }
              if (primFields.size() != keyFields.size())
              {
                  throw new ConstraintException("The number of foreignkeys ("+keyFields.size()+") of the collection "+collDef.getName()+" in class "+collDef.getOwner().getName()+" doesn't match the number of primarykeys ("+primFields.size()+") of its owner class "+ownerClass.getName());
              }
              for (int idx = 0; idx < keyFields.size(); idx++)
              {
                  keyField  = (FieldDescriptorDef)keyFields.get(idx);
                  if (keyField.getBooleanProperty(PropertyHelper.OJB_PROPERTY_IGNORE, false))
                  {
                      throw new ConstraintException("The collection "+collDef.getName()+" in class "+ownerClass.getName()+" uses the field "+keyField.getName()+" as foreignkey although this field is ignored in the element class (or its subclass) "+elementClass.getName());
                  }
              }
              // the jdbc types of the primary keys must match the jdbc types of the foreignkeys (in the correct order)
              for (int idx = 0; idx < primFields.size(); idx++)
              {
                  keyField  = (FieldDescriptorDef)keyFields.get(idx);
                  if (keyField.getBooleanProperty(PropertyHelper.OJB_PROPERTY_IGNORE, false))
                  {
                      throw new ConstraintException("The collection "+collDef.getName()+" in class "+ownerClass.getName()+" uses the field "+keyField.getName()+" as foreignkey although this field is ignored in the element class (or its subclass) "+elementClass.getName());
                  }
                  primField = (FieldDescriptorDef)primFields.get(idx);
                  primType  = primField.getProperty(PropertyHelper.OJB_PROPERTY_JDBC_TYPE);
                  keyType   = keyField.getProperty(PropertyHelper.OJB_PROPERTY_JDBC_TYPE);
                  if (!primType.equals(keyType))
                  {
                      throw new ConstraintException("The jdbc-type of foreignkey "+keyField.getName()+" in the element class (or its subclass) "+elementClass.getName()+" used by the collection "+collDef.getName()+" in class "+ownerClass.getName()+" doesn't match the jdbc-type of the corresponding primarykey "+primField.getName());
                  }
              }
          }
      }