/** Do any required validation for this node. Throw an exception if it's incorrect. */
  public void validateNode() {
    if ((getQueryKeyOrNull() == null) && (getMapping() == null)) {
      throw QueryException.invalidQueryKeyInExpression(getName());
    }

    QueryKey queryKey = getQueryKeyOrNull();
    DatabaseMapping mapping = getMapping();

    Object theOneThatsNotNull = null;
    boolean qkIsToMany = false;
    if (queryKey != null) {
      theOneThatsNotNull = queryKey;
      qkIsToMany = queryKey.isManyToManyQueryKey() || queryKey.isOneToManyQueryKey();
    }
    boolean isNestedMapping = false;
    if (mapping != null) {
      // Bug 2847621 - Add Aggregate Collection to the list of valid items for outer join.
      if (shouldUseOuterJoin
          && (!(mapping.isOneToOneMapping()
              || mapping.isOneToManyMapping()
              || mapping.isManyToManyMapping()
              || mapping.isAggregateCollectionMapping()
              || mapping.isDirectCollectionMapping()))) {
        throw QueryException.outerJoinIsOnlyValidForOneToOneMappings(getMapping());
      }
      qkIsToMany = mapping.isCollectionMapping();
      if (index != null) {
        if (qkIsToMany) {
          CollectionMapping collectionMapping = (CollectionMapping) getMapping();
          if (collectionMapping.getListOrderField() != null) {
            index.setField(collectionMapping.getListOrderField());
            if (collectionMapping.shouldUseListOrderFieldTableExpression()) {
              Expression newBase = getTable(collectionMapping.getListOrderField().getTable());
              index.setBaseExpression(newBase);
            } else {
              addDerivedField(index);
            }
          } else {
            throw QueryException.indexRequiresCollectionMappingWithListOrderField(
                this, collectionMapping);
          }
        } else {
          throw QueryException.indexRequiresCollectionMappingWithListOrderField(this, mapping);
        }
      }
      isNestedMapping = mapping.isNestedTableMapping();
      theOneThatsNotNull = mapping;
    } else {
      if (index != null) {
        throw QueryException.indexRequiresCollectionMappingWithListOrderField(this, null);
      }
    }
    if ((!shouldQueryToManyRelationship()) && qkIsToMany && (!isNestedMapping)) {
      throw QueryException.invalidUseOfToManyQueryKeyInExpression(theOneThatsNotNull);
    }
    if (shouldQueryToManyRelationship() && !qkIsToMany) {
      throw QueryException.invalidUseOfAnyOfInExpression(theOneThatsNotNull);
    }
  }
 /** INTERNAL: Used for cloning. */
 protected void postCopyIn(Map alreadyDone) {
   super.postCopyIn(alreadyDone);
   if (index != null) {
     index = (IndexExpression) index.copiedVersionFrom(alreadyDone);
   }
 }