[hibernate-commits] Hibernate SVN: r15747 - in core/branches/SQL_GEN_REDESIGN: src/main/antlr and 27 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jan 6 15:11:14 EST 2009


Author: steve.ebersole at jboss.com
Date: 2009-01-06 15:11:13 -0500 (Tue, 06 Jan 2009)
New Revision: 15747

Added:
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/resolve/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/resolve/path/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java
Removed:
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/
Modified:
   core/branches/SQL_GEN_REDESIGN/pom.xml
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java
   core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java
   core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java
   core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties
Log:
HHH-2407 : HQL translation rework ->
HHH-3687 : parse (phase1)
HHH-3688 : normalize (phase2)

Modified: core/branches/SQL_GEN_REDESIGN/pom.xml
===================================================================
--- core/branches/SQL_GEN_REDESIGN/pom.xml	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/pom.xml	2009-01-06 20:11:13 UTC (rev 15747)
@@ -185,14 +185,34 @@
                 <version>${antlrPluginVersion}</version>
                 <configuration>
                     <traceParser>true</traceParser>
+                    <traceTreeParser>true</traceTreeParser>
                     <grammarDefs>
                         <grammar>
                           <name>sql/common.g</name>
                         </grammar>
                         <grammar>
                             <name>hql/parse.g</name>
-                            <glib>sql/common.g</glib>
                         </grammar>
+                        <grammar>
+                            <name>hql/normalize.g</name>
+                        </grammar>
+                        <grammar>
+                            <name>order/parse.g</name>
+                        </grammar>
+                        <grammar>
+                            <name>order/render.g</name>
+                        </grammar>
+                        <!-- temporary -->
+                        <grammar>
+                            <name>hql.g</name>
+                        </grammar>
+                        <grammar>
+                            <name>hql-sql.g</name>
+                        </grammar>
+                        <grammar>
+                            <name>sql-gen.g</name>
+                        </grammar>
+                        <!-- / temporary -->
                     </grammarDefs>
                 </configuration>
                 <executions>
@@ -208,6 +228,6 @@
     </build>
 
     <properties>
-        <antlrPluginVersion>2.1</antlrPluginVersion>
+        <antlrPluginVersion>2.2-SNAPSHOT</antlrPluginVersion>
     </properties>
 </project>

Copied: core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g (from rev 15693, core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/resolve.g)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,1099 @@
+header {
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ * Portions of SQL grammar parsing copyright (C) 2003 by Lubos Vnuk.  All rights
+ * reserved.  These portions are distributed under license by Red Hat Middleware
+ * LLC and are covered by the above LGPL notice.  If you redistribute this material,
+ * with or without modification, you must preserve this copyright notice in its
+ * entirety.
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.DetailedSemanticException;
+}
+
+/**
+ * An Antlr tree parser for "resolving" or "normalizing" an HQL syntax AST.  This
+ * parser provides the vast majority of the semantic analysis of the HQL AST.
+ * <p/>
+ * Both "resolving" and "normalizing" here seek a single goal of building a
+ * dis-ambiguated, generic query AST.
+ * <p/>
+ * The act of resolving is essentially the process of simplifying complex node
+ * structures into atomic components based on contextual information (aka, the
+ * current parser state).  The main thrust of this process is breaking down
+ * dot-structures (a series of DOT INDET pairs) into <ul>
+ * <li>a series of "implicit" join structures injected into the from clause tree</li>
+ * <li>a simple structure representing the "meaning" of the "leaf" of said dot-structure</li>
+ * </ul>
+ * <p/>
+ * The act of normalizing essentially refers to the process of dis-ambiguating
+ * node structures based on their context and creating a unified AST
+ * representation for different ways to express the same "idea".  An example of this
+ * is normalizing implicit join dot-structures into a structure akin to its explicit
+ * join corollary.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+class GeneratedHqlNormalizer extends TreeParser;
+
+options {
+	importVocab = HqlParse;
+	exportVocab = HqlNormalize;
+	buildAST = true;
+}
+
+tokens {
+	PROPERTY_REF;
+}
+
+
+// -- Declarations --
+{
+    private static Logger log = LoggerFactory.getLogger( GeneratedHqlNormalizer.class );
+
+	private int ordinalParamCount = 0;
+
+
+    // persister reference related actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    protected AST normalizeEntityName(AST node) throws SemanticException {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST normalizeAlias(AST node) {
+        if ( node != null ) {
+            return node;
+        }
+        String syntheticAlias = buildUniqueImplicitAlias();
+        return #([ALIAS,syntheticAlias]);
+    }
+
+    protected String buildUniqueImplicitAlias() {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected void registerPersisterReference(AST reference) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected boolean isPersisterReferenceAlias(AST alias) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected boolean isCollectionPersisterReferenceAlias(AST alias) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+
+    // property reference related actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    protected final boolean isUnqualifiedPropertyReference(AST property) {
+        return locateOwningPersisterAlias( property ) != null;
+    }
+
+    protected final AST normalizeUnqualifiedPropertyReference(AST property) {
+        return #( [PROPERTY_REF], owningPersisterAliasReference( property ), property );
+    }
+
+    protected final AST owningPersisterAliasReference(AST property) {
+        return #( [ALIAS_REF,locateOwningPersisterAlias(property)] );
+    }
+
+    protected String locateOwningPersisterAlias(AST property) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+
+	// path normalization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    protected AST normalizeQualifiedRoot(AST alias) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST normalizeUnqualifiedRoot(AST alias) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST normalizeIndexedRoot(AST alias) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST normalizePropertyPathIntermediary(AST source, AST propertyNameNode) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST normalizePropertyPathTerminus(AST source, AST propertyNameNode) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+
+	// Statement node BEGIN/END handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected void pushStatement(AST statementNode) {
+	}
+
+	protected void popStatement() {
+	}
+
+
+	// property-path context pushing/popping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected void pushFromClausePropertyPathContext(AST joinType, AST fetch, AST alias, AST propertyFetch) {
+	}
+
+	protected void popFromClausePropertyPathContext() {
+	}
+
+    protected void pushSelectClausePropertyPathContext() {
+    }
+
+    protected void popSelectClausePropertyPathContext() {
+    }
+
+	protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+	}
+
+	protected void popOnFragmentPropertyPathContext() {
+	}
+
+	protected void pushWithFragmentPropertyPathContext(AST rhsPersisterReference) {
+	}
+
+	protected void popWithFragmentPropertyPathContext() {
+	}
+
+
+
+
+    // function processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    protected void startingFunction() {
+    }
+
+    protected void endingFunction() {
+    }
+
+
+
+
+    protected void registerSelectItem(AST selectItem) {
+    }
+
+
+
+
+
+	protected AST resolveAlias(AST alias) {
+		return alias;
+	}
+
+    /**
+     * Validate the operands to the index operator '[]'.  Specifically, the left-hand operand should be a reference
+     * to some form of indexed collection (map or list) and the right-hand operand should be a value expression
+     * whose type is the same as the indexed collection's index values.
+     *
+     * @param collectionPropertyReference The left-hand operand.  Should resolve to an indexed collection
+     * @param selector the right-hand operand.  Should resolve to a value type compatible with the collection's
+     * index type.
+     */
+    protected void validateIndexOperationOperands(AST collectionPropertyReference, AST selector) {
+    }
+
+
+	// persister reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected AST buildEntityPersisterReference(AST entityName, AST alias, AST propertyFetch) {
+		return entityName;
+	}
+
+	protected AST buildAdHocJoinNode(AST persisterReference, AST joinType, AST withFragment) {
+		return persisterReference;
+	}
+
+	protected void applyWithFragment(AST withFragment) {
+	}
+
+    protected void injectSelectAlias( AST selectExpression, AST alias) {
+    }
+
+    protected void registerSelectExpression(AST selectExpression) {
+    }
+
+    protected AST handleSelectedPropertyRef(AST propertyRef) {
+        return propertyRef;
+    }
+
+}
+
+// Statement rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * The main grammar rule
+ */
+statement :
+    updateStatement
+    | deleteStatement
+    | insertStatement
+    | selectStatement
+;
+
+
+// <tt>UPDATE</tt> statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an <tt>UPDATE</tt> statement
+ */
+updateStatement :
+    #(
+        UPDATE { pushStatement( #updateStatement ); }
+	        (VERSIONED)?
+	        ENTITY_NAME (ALIAS)?
+	        setClause
+	        (whereClause)? { popStatement(); }
+    )
+;
+
+setClause :
+    #( SET (assignment)+ )
+;
+
+assignment :
+    #( ASSIGNMENT_OP assignmentField newValue )
+;
+
+assignmentField :
+    propertyReference
+;
+
+newValue :
+    valueExpression
+;
+
+
+
+// <tt>DELETE</tt> statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>DELETE</tt> statement
+ */
+deleteStatement :
+    #(
+	    DELETE { pushStatement( #deleteStatement ); }
+	        ENTITY_NAME (ALIAS)?
+	        (whereClause)? { popStatement(); }
+    )
+;
+
+
+// <tt>INSERT</tt> statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>INSERT</tt> statement
+ */
+insertStatement :
+    #(
+        INSERT { pushStatement( #insertStatement ); }
+            intoClause
+            queryExpression { popStatement(); }
+    )
+;
+
+intoClause :
+    #( INTO ENTITY_NAME insertabilitySpecification )
+;
+
+insertabilitySpecification :
+    #( INSERTABILITY_SPEC (insertablePropertySpecification)+ )
+;
+
+/**
+ * The property being inserted into.
+ */
+insertablePropertySpecification :
+    IDENT
+;
+
+
+// <tt>SELECT</tt> statement rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>SELECT</tt> statement.
+ * <p/>
+ * This corresponds most closely to the <cursor specification> rule in ISO/ANSI SQL...
+ */
+selectStatement :
+    #( QUERY { pushStatement( #selectStatement ); } queryExpression (orderByClause)? ) { popStatement(); }
+;
+
+orderByClause :
+    #( ORDER_BY (sortSpecification)+ )
+;
+
+sortSpecification :
+    #( SORT_SPEC sortKey (collationSpecification)? (orderingSpecification)? )
+;
+
+sortKey :
+    // todo : do we want to explicitly limit these?
+    valueExpression
+;
+
+collationSpecification :
+    COLLATE
+;
+
+orderingSpecification :
+    ORDER_SPEC
+;
+
+queryExpression :
+    querySpec ( ( UNION | INTERSECT | EXCEPT ) (ALL)? querySpec )*
+;
+
+subquery :
+    queryExpression
+;
+
+querySpec :
+    #( QUERY_SPEC selectFrom ( whereClause )? ( groupByClause ( havingClause )? )? )
+;
+
+
+selectFrom :
+    #( SELECT_FROM fromClause (selectClause)? )
+;
+
+
+// table/persister related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+fromClause :
+    #( FROM (persisterSpace)+ )
+;
+
+persisterSpace :
+    #( PERSISTER_SPACE entityPersisterReference ( explicitJoin )* )
+;
+
+entityPersisterReference! :
+    #( epr:ENTITY_PERSISTER_REF en:ENTITY_NAME (a:ALIAS)? (pf:PROP_FETCH)? ) {
+//		#entityPersisterReference = buildEntityPersisterReference( en, a, pf );
+        AST entityName = normalizeEntityName( #en );
+        AST alias = normalizeAlias( #a );
+		#entityPersisterReference = #( #epr, entityName, alias, #pf );
+		registerPersisterReference( #entityPersisterReference );
+	}
+;
+
+explicitJoin :
+    explicitPersisterJoin
+    | explicitPropertyJoin
+;
+
+explicitPersisterJoin :
+    #(
+        j:PERSISTER_JOIN (
+            CROSS entityPersisterReference
+            | qualifiedJoinType e:entityPersisterReference (on:onFragment[#e])?
+        )
+    ) {
+        #j.setType( JOIN );
+        #j.setText( "join" );
+    }
+;
+
+explicitPropertyJoin! :
+    #( j:PROPERTY_JOIN jt:qualifiedJoinType (f:FETCH)? (a:ALIAS)? (pf:PROP_FETCH)? {pushFromClausePropertyPathContext(#jt,#f,#a,#pf);} prop:propertyReference (with:withFragment[#prop])? {popFromClausePropertyPathContext();} )
+;
+
+qualifiedJoinType :
+    ( (LEFT | RIGHT) (OUTER)? )
+	| INNER
+;
+
+onFragment[ AST rhsPersisterReference ] :
+    #( o:ON { pushOnFragmentPropertyPathContext( rhsPersisterReference ); } sc:searchCondition ) {
+		#onFragment = #( o, sc );
+	}
+;
+
+withFragment[ AST rhsPropertyReference ] :
+    #( w:WITH { pushWithFragmentPropertyPathContext( rhsPropertyReference ); }  sc:searchCondition ) {
+		#withFragment = #( w, sc );
+		applyWithFragment( #withFragment );
+		popWithFragmentPropertyPathContext();
+	}
+;
+
+
+// select clause related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+selectClause :
+    #( SELECT (d:DISTINCT)? { pushSelectClausePropertyPathContext(); } rootSelectExpression ) {
+		popSelectClausePropertyPathContext();
+	}
+;
+
+rootSelectExpression :
+    #( SELECT_LIST explicitSelectList )
+    | #( SELECT_ITEM ( rootDynamicInstantiation | jpaSelectObjectSyntax ) )
+;
+
+explicitSelectList :
+    ( explicitSelectItem )+
+;
+
+explicitSelectItem :
+    #( SELECT_ITEM selectExpression ) {
+        registerSelectItem( #explicitSelectItem );
+    }
+;
+
+selectExpression :
+    valueExpression ( ALIAS )?
+;
+
+rootDynamicInstantiation :
+    #( DYNAMIC_INSTANTIATION dynamicInstantiationArguments ) {
+        registerSelectItem( #rootDynamicInstantiation );
+    }
+;
+
+nestedDynamicInstantiation :
+    #( DYNAMIC_INSTANTIATION dynamicInstantiationArguments (ALIAS)? )
+;
+
+dynamicInstantiationArguments :
+    ( dynamicInstantiationArgument )+
+;
+
+dynamicInstantiationArgument :
+    #( DYNAMIC_INSTANTIATION_ARG ( nestedDynamicInstantiation | selectExpression ) )
+;
+
+jpaSelectObjectSyntax! :
+    #( SELECT_ITEM OBJECT a:ALIAS_REF ) {
+        if ( isPersisterReferenceAlias( #a ) ) {
+            #jpaSelectObjectSyntax = #a;
+        }
+        else {
+            throw new DetailedSemanticException( "token [" + #a.getText() + "] in syntax [object (" + #a.getText() + ")] must refer to persister reference", #a );
+        }
+    }
+;
+
+
+
+// where clause rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+whereClause :
+    #( WHERE searchCondition )
+;
+
+
+
+// group by clause rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+groupByClause :
+    #( GROUP_BY groupingSpecification )
+;
+
+groupingSpecification :
+    ( groupingValue )+
+;
+
+groupingValue :
+    valueExpression ( collationSpecification )?
+;
+
+
+
+// having clause related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+havingClause :
+    #( HAVING searchCondition )
+;
+
+
+
+// value/expression recognition rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+numericValueExpression :
+	valueExpression
+;
+
+stringValueExpression :
+	characterValueExpression
+;
+
+characterValueExpression :
+    valueExpression
+;
+
+intervalValueExpression :
+	valueExpression
+;
+
+datetimeValueExpression :
+	valueExpression
+;
+
+valueExpression :
+    #( CONCATENATION_OP ARGLIST ( characterValueExpression )+ )
+    | #( UNARY_MINUS numericValueExpression )
+    | #( UNARY_PLUS numericValueExpression )
+    | #( PLUS_SIGN valueExpression valueExpression )
+    | #( MINUS_SIGN valueExpression valueExpression )
+    | #( ASTERISK numericValueExpression numericValueExpression )
+    | #( SOLIDUS numericValueExpression numericValueExpression )
+    | valueExpressionPrimary
+;
+
+valueExpressionPrimary :
+    (persisterReferenceAliasCheck) => nonCollectionPersisterAliasReference
+    | caseExpression
+//	| quantifiedExpression
+	| function
+	| collectionFunction
+	| collectionExpression
+	| literal
+	| parameter
+    | propertyReference
+;
+
+
+function : {
+        startingFunction();
+    }
+    ( standardFunction | setFunction ) {
+        endingFunction();
+    }
+;
+
+nonCollectionPersisterAliasReference :
+    a:persisterAliasReference {
+        if ( isCollectionPersisterReferenceAlias( #a ) ) {
+            throw new DetailedSemanticException( "expecting non-collection alias reference [" + #a.getText() + "]", #a );
+        }
+    }
+;
+
+persisterAliasReference :
+    ALIAS_REF
+    | a:IDENT { isPersisterReferenceAlias( #a ) }? {
+        #a.setType( ALIAS_REF );
+    }
+;
+
+caseExpression :
+    caseAbbreviation
+    | caseSpecification
+;
+
+caseAbbreviation :
+    #( NULLIF valueExpression valueExpression )
+    | #( COALESCE ( valueExpression )+ )
+;
+
+caseSpecification :
+    simpleCase
+     | searchedCase
+;
+
+simpleCase :
+    #( SIMPLE_CASE valueExpression (simpleCaseWhenClause)+ (elseClause)? END )
+;
+
+simpleCaseWhenClause :
+    #( WHEN valueExpression THEN result )
+;
+
+result :
+    valueExpression
+;
+
+elseClause :
+    #( ELSE result )
+;
+
+searchedCase :
+    #( SEARCHED_CASE (searchedWhenClause)+ (elseClause)? END )
+;
+
+searchedWhenClause :
+    #( WHEN searchCondition THEN valueExpression )
+;
+
+//quantifiedExpression :
+//    // todo : this should be a function of the predicates (logicalExpression) not of concatenation/additiveExpression
+//    //      they can come only in very certain circumstances.
+//	#( ( SOME^ | EXISTS^ | ALL^ | ANY^ ) ( IDENT | collectionExpression | (LEFT_PAREN! ( subQuery ) RIGHT_PAREN!) ) )
+//;
+
+standardFunction :
+    castFunction
+    | concatFunction
+    | substringFunction
+    | trimFunction
+    | upperFunction
+    | lowerFunction
+    | lengthFunction
+    | locateFunction
+    | absFunction
+    | sqrtFunction
+    | modFunction
+    | sizeFunction
+    | indexFunction
+    | currentDateFunction
+    | currentTimeFunction
+    | currentTimestampFunction
+    | extractFunction
+    | positionFunction
+    | charLengthFunction
+    | octetLengthFunction
+    | bitLengthFunction
+;
+
+castFunction :
+    #( CAST valueExpression dataType )
+;
+
+dataType :
+    // todo : temp...
+    IDENT
+;
+
+concatFunction :
+    #( CONCAT (valueExpression)* )
+;
+
+substringFunction :
+    #( SUBSTRING characterValueExpression numericValueExpression (numericValueExpression)? )
+;
+
+trimFunction :
+    #( TRIM  ( LEADING | TRAILING | BOTH ) CHAR_STRING characterValueExpression )
+;
+
+upperFunction :
+    #( UPPER characterValueExpression )
+;
+
+lowerFunction :
+    #( LOWER characterValueExpression )
+;
+
+lengthFunction :
+    #( LENGTH characterValueExpression )
+;
+
+locateFunction :
+    #( LOCATE characterValueExpression characterValueExpression (numericValueExpression)? )
+;
+
+absFunction :
+    #( ABS numericValueExpression )
+;
+
+sqrtFunction :
+    #( SQRT numericValueExpression )
+;
+
+modFunction :
+    #( MOD numericValueExpression numericValueExpression )
+;
+
+sizeFunction :
+    #( SIZE collectionPropertyReference )
+;
+
+indexFunction :
+    #( INDEX ALIAS_REF )
+;
+
+currentDateFunction :
+    CURRENT_DATE
+;
+
+currentTimeFunction :
+    CURRENT_TIME
+;
+
+currentTimestampFunction :
+    CURRENT_TIMESTAMP
+;
+
+extractFunction :
+    #( EXTRACT extractField FROM extractSource )
+;
+
+extractField :
+    datetimeField
+	| timeZoneField
+;
+
+datetimeField :
+    nonSecondDatetimeField
+	| SECOND
+;
+
+timeZoneField :
+    TIMEZONE_HOUR
+    | TIMEZONE_MINUTE
+;
+
+extractSource :
+    datetimeValueExpression
+;
+
+positionFunction :
+    #( POSITION characterValueExpression characterValueExpression )
+;
+
+charLengthFunction :
+    #( CHAR_LENGTH characterValueExpression )
+    | #( CHARACTER_LENGTH characterValueExpression )
+;
+
+octetLengthFunction :
+    #( OCTET_LENGTH characterValueExpression )
+;
+
+bitLengthFunction :
+    #( BIT_LENGTH characterValueExpression )
+;
+
+setFunction :
+    #( SUM numericValueExpression )
+    | #( AVG numericValueExpression )
+    | #( MAX numericValueExpression )
+    | #( MIN numericValueExpression )
+    | #( COUNT {startingFunction();} ( ASTERISK | ( ( DISTINCT | ALL )? ( propertyReference | literal ) ) ) {endingFunction();} )
+;
+
+collectionFunction :
+    #( MAXELEMENT collectionPropertyReference )
+    | #( MAXINDEX collectionPropertyReference )
+    | #( MINELEMENT collectionPropertyReference )
+    | #( MININDEX collectionPropertyReference )
+;
+
+collectionExpression :
+    #( ELEMENTS collectionPropertyReference )
+    #( INDICES collectionPropertyReference )
+;
+
+parameter :
+    p:PARAM { p.setText( Integer.toString( ordinalParamCount++ ) ); }  // todo : move this to parse?
+    | JPA_PARAM
+    | NAMED_PARAM
+;
+
+
+// literals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+protected
+literal :
+    javaConstant
+    | numericLiteral
+    | characterLiteral
+    | dateLiteral
+    | timeLiteral
+    | timestampLiteral
+    | intervalLiteral
+;
+
+protected
+javaConstant :
+    JAVA_CONSTANT
+;
+
+protected
+numericLiteral :
+    UNSIGNED_INTEGER
+    | NUM_INT_LITERAL
+    | NUM_LONG_LITERAL
+    | NUM_DOUBLE_LITERAL
+    | NUM_FLOAT_LITERAL
+;
+
+protected
+characterLiteral :
+    CHAR_STRING
+    | NATIONAL_CHAR_STRING_LIT
+	| BIT_STRING_LIT
+	| HEX_STRING_LIT
+;
+
+protected
+dateLiteral :
+//    #( DATE CHAR_STRING )
+    #( DATE characterValueExpression )
+;
+
+protected
+timeLiteral :
+//    #( TIME CHAR_STRING )
+    #( TIME characterValueExpression )
+;
+
+protected
+timestampLiteral :
+//    #( TIMESTAMP CHAR_STRING )
+    #( TIMESTAMP characterValueExpression )
+;
+
+protected
+intervalLiteral :
+    #( INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier )
+//    #( INTERVAL ( PLUS_SIGN | MINUS_SIGN )? characterValueExpression intervalQualifier )  -- characterValueExpression causes non-determinism with + and -
+;
+
+protected
+intervalQualifier :
+    #( YEAR (precision)? ( TO MONTH )? )
+    | #( MONTH (precision)? )
+    | #( DAY (precision)? ( TO ( HOUR | MINUTE | ( SECOND (scale)? ) ) )? )
+    | #( HOUR (precision)? ( TO ( MINUTE | SECOND (scale)? ) )? )
+    | #( MINUTE (precision)? ( TO SECOND (scale)? )? )
+    | #( SECOND ( precision (scale)? )? )
+;
+
+precision :
+    NUM_INT_LITERAL
+;
+
+scale :
+    NUM_INT_LITERAL
+;
+
+//protected
+//intervalStartField :
+//    nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+//
+//protected
+//intervalEndField :
+//    nonSecondDatetimeField
+//	| SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+
+protected
+nonSecondDatetimeField :
+    YEAR
+    | MONTH
+    | DAY
+    | HOUR
+    | MINUTE
+;
+
+
+
+// property-reference related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+nonCollectionPropertyReference :
+    pr:propertyReference {
+        // todo : validate the property type
+    }
+;
+
+collectionPropertyReference :
+    pr:propertyReference {
+        // todo : validate the property type
+    }
+;
+
+/**
+ * The top level property ref recognition rule.
+ */
+propertyReference :
+    (unqualifiedPropertyReferenceCheck) => unqualifiedPropertyReference
+    | pathedPropertyReference
+    | indexOperation
+;
+
+/**
+ * A rule utilizing a validating semantic predicate to contextually
+ * ensure that we have unqualified property reference.  Generally
+ * used from within syntactic predicates to disambiguate the match path
+ *
+ * see {@link #implicitJoinSource} for example
+ */
+unqualifiedPropertyReferenceCheck! :
+    prop:IDENT { isUnqualifiedPropertyReference( prop ) }?
+;
+
+/**
+ * AST construction rule for building AST relating to *known*
+ * unqualified property references.  Do not call this rule unless
+ * you know for certain (ala, have verified via the unqualifiedPropertyRefCheck
+ * rule or similiar) that the next token is an IDENT representing an
+ * unqualified property reference.
+ */
+unqualifiedPropertyReference! :
+    prop:IDENT {
+        #unqualifiedPropertyReference = normalizeUnqualifiedPropertyReference( prop );
+    }
+;
+
+/**
+ * Perhaps better named as 'complex property ref' or 'pathed property ref' i.e.
+ * Anyway, the basic idea is (DOT <source> IDENT)
+ */
+pathedPropertyReference! :
+    #( d:DOT source:pathedPropertyReferenceSource prop:IDENT) {
+        #pathedPropertyReference = normalizePropertyPathTerminus( #source, #prop );
+    }
+;
+
+/**
+ * The output of the implicitJoinSource rule is a {@link org.hibernate.sql.ast.phase.resolve.patg.PropertyPathPart}
+ * reference which is a tokenized and encoded representation of the current path expression
+ * resolution state.
+ */
+pathedPropertyReferenceSource :
+    (persisterReferenceAliasCheck) => a:IDENT { #pathedPropertyReferenceSource = normalizeQualifiedRoot( #a ); }
+    | (unqualifiedPropertyReferenceCheck) => pr:IDENT { #pathedPropertyReferenceSource = normalizeUnqualifiedRoot( #pr ); }
+    | intermediatePathedPropertyReference
+    | i:indexOperation { #pathedPropertyReferenceSource = normalizeIndexedRoot( #i ); }
+;
+
+/**
+ * A rule utilizing a validating semantic predicate to contextually
+ * ensure that we have an alias for a persister reference previously
+ * encountered and processed.  Generally used from within syntactic
+ * predicates to disambiguate the path.
+ */
+persisterReferenceAliasCheck! :
+    alias:IDENT { isPersisterReferenceAlias( alias ) }?
+;
+
+/**
+ * AST construction rule for building AST relating to *known*
+ * persister reference aliases.  Do not call this rule unless
+ * you know for certain (ala, have verified via the persisterReferenceAliasCheck
+ * rule or similiar) that the next token is an IDENT representing an
+ * alias for a persister reference
+ */
+persisterReferenceAlias! :
+    alias:IDENT {
+        #persisterReferenceAlias = resolveAlias( alias );
+    }
+;
+
+intermediatePathedPropertyReference! :
+    #( d:DOT source:pathedPropertyReferenceSource prop:IDENT ) {
+        #intermediatePathedPropertyReference = normalizePropertyPathIntermediary( #source, #prop );
+    }
+;
+
+indexOperation
+    : #( i:INDEX_OP coll:collectionPropertyReference selector:indexSelector ) {
+        validateIndexOperationOperands( #coll, #selector );
+    }
+    ;
+
+indexSelector
+	: valueExpression
+//	| literal
+//	| parameter
+//	| collectionFunctionCall : "index(alias)"
+	;
+
+
+// Search conditions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Main logical/conditional rule defining boolean evaluated expressions
+ * <p/>
+ * This first level handles OR expressions
+ */
+searchCondition :
+    #( OR searchCondition searchCondition )
+    | #( AND searchCondition searchCondition )
+    | #( NOT searchCondition )
+    | predicate
+;
+
+predicate :
+    #( EQUALS_OP rowValueConstructor comparativePredicateValue )
+    | #( NOT_EQUALS_OP rowValueConstructor comparativePredicateValue )
+    | #( LESS_THAN_OP rowValueConstructor comparativePredicateValue )
+    | #( LESS_THAN_OR_EQUALS_OP rowValueConstructor comparativePredicateValue )
+    | #( GREATER_THAN_OP rowValueConstructor comparativePredicateValue )
+    | #( GREATER_THAN_OR_EQUALS_OP rowValueConstructor comparativePredicateValue )
+    | #( IS_NULL rowValueConstructor )
+    | #( IS_NOT_NULL rowValueConstructor )
+    | #( LIKE valueExpression valueExpression (escapeSpecification)? )
+    | #( NOT_LIKE valueExpression valueExpression (escapeSpecification)? )
+	| #( BETWEEN rowValueConstructor rowValueConstructor rowValueConstructor )
+	| #( NOT_BETWEEN rowValueConstructor rowValueConstructor rowValueConstructor )
+	| #( IN rowValueConstructor inPredicateValue )
+	| #( NOT_IN rowValueConstructor inPredicateValue )
+	| #( EXISTS (
+	        queryExpression
+	        | ( ELEMENTS | INDICES ) collectionPropertyReference
+	    )
+	)
+;
+
+comparativePredicateValue :
+    rowValueConstructor
+    | ( ( SOME | ALL | ANY ) subquery )
+;
+
+escapeSpecification :
+    #( ESCAPE characterValueExpression )
+;
+
+inPredicateValue :
+    #(
+        IN_LIST (
+            queryExpression
+            | ( valueExpression )+
+        )
+    )
+;
+
+rowValueConstructor :
+    ( LEFT_PAREN ) => ( LEFT_PAREN rowValueConstructorList RIGHT_PAREN )
+    | rowValueConstructorElement
+;
+
+rowValueConstructorElement :
+    valueExpression
+    | NULL
+    | DEFAULT
+;
+
+rowValueConstructorList :
+    rowValueConstructorElement ( COMMA! rowValueConstructorElement )*
+;
+

Modified: core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g	2009-01-06 20:11:13 UTC (rev 15747)
@@ -28,7 +28,7 @@
  * with or without modification, you must preserve this copyright notice in its
  * entirety.
  */
-package org.hibernate.hql.ast.phase.parse;
+package org.hibernate.sql.ast.phase.hql.parse;
 
 import antlr.collections.AST;
 
@@ -60,10 +60,12 @@
 	ALIAS_REF;
 	ARG_LIST;
 	ASSIGNMENT_OP;
-	CLASS_NAME;
-	CONSTRUCTOR;
+	COLLECTION_PERSISTER_REF;
 	COLLECTION_ROLE;
+	DYNAMIC_INSTANTIATION;
+	DYNAMIC_INSTANTIATION_ARG;
 	ENTITY_NAME;
+	ENTITY_PERSISTER_REF;
 	FILTER_ENTITY;
 	GENERIC_FUNCTION;
 	INDEX_OP;
@@ -78,26 +80,31 @@
 	NOT_IN;
 	NOT_LIKE;
     ORDER_SPEC;
+	PERSISTER_SPACE;
 	PROP_FETCH;
 	QUERY;
+	QUERY_SPEC;
     REGISTERED_FUNCTION;
+    SEARCHED_CASE;
 	SELECT_FROM;
+    SELECT_ITEM;
+    SELECT_LIST;
+	SIMPLE_CASE;
     SORT_KEY;
     SORT_SPEC;
     SQL_TOKEN;
 	UNARY_MINUS;
 	UNARY_PLUS;
-	PERSISTER_SPACE;
-//	WEIRD_IDENT;
 
-//    AGGREGATE;
 	EXPR_LIST;
-//	ROW_STAR;
 	VECTOR_EXPR;
+
+	PERSISTER_JOIN;
+	PROPERTY_JOIN;
 }
 
 {
-    private static Logger log = LoggerFactory.getLogger( GeneratedHqlParser99.class );
+    private static Logger log = LoggerFactory.getLogger( GeneratedHqlParser.class );
 
     protected String extractText(AST node) {
         return node.getText();
@@ -107,6 +114,10 @@
         return extractText( node );
     }
 
+    protected String normalizeDynamicInstantiationClassName(AST node) {
+        return extractPath( node );
+    }
+
 	protected boolean isJavaConstant(String test) {
 		return false;
 	}
@@ -208,16 +219,7 @@
     }
 ;
 
-protected
-className :
-    p:path {
-		String name = extractPath( #p );
-        #className = #( [CLASS_NAME,name] );
-        transferTrackingInfo( #p, #className );
-    }
-;
 
-
 // alias/correlation recognition rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 /**
@@ -361,7 +363,7 @@
 ;
 
 orderByClause :
-    ORDER^ BY! sortSpecification ( COMMA! sortSpecification )*
+    ORDER_BY^ sortSpecification ( COMMA! sortSpecification )*
 ;
 
 /**
@@ -415,9 +417,9 @@
 ;
 
 querySpec :
-    selectFrom
-        ( whereClause )?
-        ( groupByClause ( havingClause )? )?
+    selectFrom ( whereClause )? ( groupByClause ( havingClause )? )? {
+        #querySpec = #( [QUERY_SPEC], #querySpec );
+    }
 ;
 
 selectFrom! :
@@ -476,43 +478,49 @@
         CLASS! {unequivocalKeywordAsIdentifier();} en:entityName! {
             log.warn( "encountered deprecated, legacy from-clause syntax : [<alias> in class <entity-name>]" );
             #a.setType( ALIAS );
-            #hibernateLegacySyntax = #( #en, #a );
+            #hibernateLegacySyntax = #( [ENTITY_PERSISTER_REF], #en, #a );
         }
         | ( ELEMENTS! | INDICES! )? LEFT_PAREN! {unequivocalKeywordAsIdentifier();} p:path! RIGHT_PAREN! {
             log.warn( "encountered deprecated, legacy from-clause syntax : [<alias> in <elements|indices> (<collection-ref>)]" );
             // todo : properly treat ELEMENTS | INDICES...
             #a.setType( ALIAS );
-            #hibernateLegacySyntax = #( [JOIN,"join"], [INNER, "inner"], #p, #a );
+            #hibernateLegacySyntax = #( [PROPERTY_JOIN,"property-join"], [INNER, "inner"], #a, #p );
         }
     )
 ;
 
-mainEntityPersisterReference :
-    entityName (alias)? (propertyFetch)?
+mainEntityPersisterReference! :
+    en:entityName (a:alias)? (pf:propertyFetch)? {
+        #mainEntityPersisterReference = #( [ENTITY_PERSISTER_REF], #en, #a, #pf );
+    }
 ;
 
 jpaCollectionReference :
-    IN! LEFT_PAREN! {unequivocalKeywordAsIdentifier();} p2:path RIGHT_PAREN! ( a2:alias )? {
-        #jpaCollectionReference = #( [JOIN,"join"], [INNER, "inner"], #p2, #a2 );
+    IN! LEFT_PAREN! {unequivocalKeywordAsIdentifier();} p:path RIGHT_PAREN! ( a:alias )? {
+        #jpaCollectionReference = #( [PROPERTY_JOIN,"property-join"], [INNER, "inner"], #a, #p );
     }
 ;
 
 crossJoin :
-    CROSS JOIN^ {prepareForCrossJoinElements();} entityName (alias)? (propertyFetch)?
+    CROSS j:JOIN^ {prepareForCrossJoinElements();} mainEntityPersisterReference {
+        j.setType( PERSISTER_JOIN );
+        j.setText( "persister-join" );
+    }
 ;
 
 qualifiedJoin! :
     (jt:nonCrossJoinType)? j:JOIN {if (#jt==null) #jt=#([INNER]);} (f:FETCH)? {prepareForQualifiedJoinElements();} p:path (a:alias)? (
-        // try to use the ON keyword to disambiguate
+        // use the ON keyword to disambiguate
         js:joinSpecification {
             if ( #f != null ) {
                 throw new org.hibernate.QueryException( "Cannot use fetch keyword in conjunction with an ad hoc join" );
             }
             String entityName = extractPath( #p );
-            #qualifiedJoin = #( #j, #jt, [ENTITY_NAME,entityName], #a, #js );
+            AST persisterReference = #( [ENTITY_PERSISTER_REF], [ENTITY_NAME,entityName], #a );
+            #qualifiedJoin = #( [PERSISTER_JOIN,"persister-join"], #jt, persisterReference, #js );
         }
         | (pf:propertyFetch)? (w:withClause)? {
-            #qualifiedJoin = #( #j, #jt, #f, #a, #pf, #p, #w );
+            #qualifiedJoin = #( [PROPERTY_JOIN,"property-join"], #jt, #f, #a, #pf, #p, #w );
         }
     )
 ;
@@ -525,6 +533,7 @@
 outerJoinType :
     LEFT
     | RIGHT
+    | FULL // ugh!
 ;
 
 joinSpecification :
@@ -545,30 +554,67 @@
 // select clause related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-selectClause
-	: SELECT^	// NOTE: The '^' after a token causes the corresponding AST node to be the root of the sub-tree.
-		{ weakKeywords(); }	// Weak keywords can appear immediately after a SELECT token.
-		(DISTINCT)? ( selectedPropertiesList | newExpression | selectObject )
-	;
+selectClause :
+    SELECT^ (DISTINCT)? { weakKeywords(); } rootSelectExpression
+;
 
-newExpression
-	: (NEW! path) op:LEFT_PAREN^ {#op.setType(CONSTRUCTOR);} selectedPropertiesList RIGHT_PAREN!
-	;
+rootSelectExpression :
+    explicitSelectList
+    | rootDynamicInstantiation
+    | jpaSelectObjectSyntax
+;
 
-selectObject
-   : OBJECT^ LEFT_PAREN! identifier RIGHT_PAREN!
-   ;
+explicitSelectList :
+    explicitSelectItem ( COMMA! explicitSelectItem )* {
+        #explicitSelectList = #( [SELECT_LIST], #explicitSelectList );
+    }
+;
 
-selectedPropertiesList
-	: aliasedExpression ( COMMA! aliasedExpression )*
-	;
+explicitSelectItem :
+    selectExpression {
+        #explicitSelectItem = #( [SELECT_ITEM], #explicitSelectItem );
+    }
+;
 
-aliasedExpression
-	: expression ( AS^ identifier )?
-	;
+selectExpression :
+    expression ( AS! i:identifier {#i.setType(ALIAS);} )?
+;
 
+rootDynamicInstantiation! :
+	n:NEW! p:path op:LEFT_PAREN! args:dynamicInstantiationArgs RIGHT_PAREN! {
+        #rootDynamicInstantiation = #( [ DYNAMIC_INSTANTIATION, normalizeDynamicInstantiationClassName( #p ) ], #args );
+        transferTrackingInfo( #n, #rootDynamicInstantiation );
+        #rootDynamicInstantiation = #( [SELECT_ITEM], #rootDynamicInstantiation );
+        transferTrackingInfo( #n, #rootDynamicInstantiation );
+    }
+;
 
+nestedDynamicInstantiation :
+    n:NEW! p:path op:LEFT_PAREN! args:dynamicInstantiationArgs RIGHT_PAREN! ( AS! a:identifier {#a.setType(ALIAS);} )? {
+        #nestedDynamicInstantiation = #( [ DYNAMIC_INSTANTIATION, normalizeDynamicInstantiationClassName( #p ) ], #args, #a );
+        transferTrackingInfo( #n, #nestedDynamicInstantiation );
+    }
+;
 
+dynamicInstantiationArgs :
+    dynamicInstantiationArg ( COMMA! dynamicInstantiationArg )*
+;
+
+dynamicInstantiationArg :
+    ( selectExpression | nestedDynamicInstantiation ) {
+        #dynamicInstantiationArg = #( [DYNAMIC_INSTANTIATION_ARG], #dynamicInstantiationArg );
+    }
+;
+
+jpaSelectObjectSyntax :
+    OBJECT^ LEFT_PAREN! i:identifier RIGHT_PAREN! {
+        #i.setType(ALIAS_REF);
+        #jpaSelectObjectSyntax = #( [SELECT_ITEM], #jpaSelectObjectSyntax );
+    }
+;
+
+
+
 // where clause rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 whereClause :
@@ -580,7 +626,7 @@
 // group by clause rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 groupByClause :
-    GROUP^ BY! groupingSpecification
+    GROUP_BY^ groupingSpecification
 ;
 
 groupingSpecification :
@@ -758,8 +804,8 @@
 ;
 
 caseAbbreviation :
-    ( NULLIF LEFT_PAREN unaryExpression COMMA unaryExpression RIGHT_PAREN )
-    | ( COALESCE LEFT_PAREN unaryExpression (COMMA unaryExpression)* RIGHT_PAREN )
+    ( NULLIF^ LEFT_PAREN! unaryExpression COMMA! unaryExpression RIGHT_PAREN! )
+    | ( COALESCE^ LEFT_PAREN! unaryExpression (COMMA! unaryExpression)* RIGHT_PAREN! )
 ;
 
 caseSpecification :
@@ -768,7 +814,9 @@
 ;
 
 simpleCase :
-    CASE unaryExpression (simpleCaseWhenClause)+ (elseClause)? END
+    c:CASE^ unaryExpression (simpleCaseWhenClause)+ (elseClause)? END {
+        #c.setType( SIMPLE_CASE );
+    }
 ;
 
 simpleCaseWhenClause :
@@ -784,7 +832,9 @@
 ;
 
 searchedCase :
-    CASE (searchedWhenClause)+ (elseClause)? END
+    c:CASE^ (searchedWhenClause)+ (elseClause)? END {
+        c.setType( SEARCHED_CASE );
+    }
 ;
 
 searchedWhenClause :
@@ -906,19 +956,19 @@
 ;
 
 currentDateFunction :
-    CURRENT_DATE ( LEFT_PAREN! RIGHT_PAREN! )?
+    CURRENT_DATE^ ( LEFT_PAREN! RIGHT_PAREN! )?
 ;
 
 currentTimeFunction :
-    CURRENT_TIME ( LEFT_PAREN! RIGHT_PAREN! )?
+    CURRENT_TIME^ ( LEFT_PAREN! RIGHT_PAREN! )?
 ;
 
 currentTimestampFunction :
-    CURRENT_TIMESTAMP ( LEFT_PAREN! RIGHT_PAREN! )?
+    CURRENT_TIMESTAMP^ ( LEFT_PAREN! RIGHT_PAREN! )?
 ;
 
 extractFunction :
-    EXTRACT^ LEFT_PAREN! extractField FROM extractSource RIGHT_PAREN!
+    EXTRACT^ LEFT_PAREN! extractField FROM! extractSource RIGHT_PAREN!
 ;
 
 extractField :
@@ -1075,64 +1125,64 @@
 	| FALSE
 ;
 
-literal :
-    numericLiteral
-    | characterLiteral
-    | dateLiteral
-    | timeLiteral
-    | timestampLiteral
-    | intervalLiteral
-;
-
-numericLiteral :
-    UNSIGNED_INTEGER
-    | NUM_INT_LITERAL
-    | NUM_LONG_LITERAL
-    | NUM_DOUBLE_LITERAL
-    | NUM_FLOAT_LITERAL
-;
-
-characterLiteral :
-    CHAR_STRING
-    | NATIONAL_CHAR_STRING_LIT
-	| BIT_STRING_LIT
-	| HEX_STRING_LIT
-;
-
-dateLiteral :
-    DATE^ CHAR_STRING
-;
-
-timeLiteral :
-    TIME^ CHAR_STRING
-;
-
-timestampLiteral :
-    TIMESTAMP^ CHAR_STRING
-;
-
-intervalLiteral :
-    INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier
-;
-
-intervalQualifier :
-    intervalStartField ( TO intervalEndField | )
-    | SECOND ( LEFT_PAREN UNSIGNED_INTEGER ( COMMA UNSIGNED_INTEGER )? RIGHT_PAREN )?
-;
-
-intervalStartField :
-    nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
-;
-
-intervalEndField :
-    nonSecondDatetimeField
-	| SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
-;
-
-nonSecondDatetimeField :
-    YEAR
-    | MONTH
-    | DAY
-    | HOUR
-    | MINUTE
-;
+//literal :
+//    numericLiteral
+//    | characterLiteral
+//    | dateLiteral
+//    | timeLiteral
+//    | timestampLiteral
+//    | intervalLiteral
+//;
+//
+//numericLiteral :
+//    UNSIGNED_INTEGER
+//    | NUM_INT_LITERAL
+//    | NUM_LONG_LITERAL
+//    | NUM_DOUBLE_LITERAL
+//    | NUM_FLOAT_LITERAL
+//;
+//
+//characterLiteral :
+//    CHAR_STRING
+//    | NATIONAL_CHAR_STRING_LIT
+//	| BIT_STRING_LIT
+//	| HEX_STRING_LIT
+//;
+//
+//dateLiteral :
+//    DATE^ CHAR_STRING
+//;
+//
+//timeLiteral :
+//    TIME^ CHAR_STRING
+//;
+//
+//timestampLiteral :
+//    TIMESTAMP^ CHAR_STRING
+//;
+//
+//intervalLiteral :
+//    INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier
+//;
+//
+//intervalQualifier :
+//    intervalStartField ( TO intervalEndField | )
+//    | SECOND ( LEFT_PAREN UNSIGNED_INTEGER ( COMMA UNSIGNED_INTEGER )? RIGHT_PAREN )?
+//;
+//
+//intervalStartField :
+//    nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+//
+//intervalEndField :
+//    nonSecondDatetimeField
+//	| SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+//
+//nonSecondDatetimeField :
+//    YEAR
+//    | MONTH
+//    | DAY
+//    | HOUR
+//    | MINUTE
+//;

Copied: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,429 @@
+header
+{
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+}
+/**
+ * Antlr grammar for dealing with <tt>order-by</tt> mapping fragments.
+ *
+ * @author Steve Ebersole
+ */
+class GeneratedOrderByFragmentParser extends Parser;
+
+options
+{
+	exportVocab=OrderByTemplate;
+	buildAST=true;
+	k=3;
+}
+
+tokens
+{
+    // synthetic tokens
+    ORDER_BY;
+    SORT_SPEC;
+    ORDER_SPEC;
+    SORT_KEY;
+    EXPR_LIST;
+    DOT;
+    IDENT_LIST;
+    COLUMN_REF;
+
+    COLLATE="collate";
+	ASCENDING="asc";
+	DESCENDING="desc";
+}
+
+
+{
+    /**
+     * Extract a node's text.
+     *
+     * @param ast The node
+     *
+     * @return The text.
+     */
+    protected final String extractText(AST ast) {
+        // for some reason, within AST creation blocks "[]" I am somtimes unable to refer to the AST.getText() method
+        // using #var (the #var is not interpreted as the rule's output AST).
+        return ast.getText();
+    }
+
+    /**
+     * Process the given node as a quote identifier.  These need to be quoted in the dialect-specific way.
+     *
+     * @param ident The quoted-identifier node.
+     *
+     * @return The processed node.
+     *
+     * @see org.hibernate.dialect.Dialect#quote
+     */
+    protected AST quotedIdentifier(AST ident) {
+        return ident;
+    }
+
+    /**
+     * Process the given node as a quote string.
+     *
+     * @param ident The quoted string.  This is used from within function param recognition, and represents a
+     * SQL-quoted string.
+     *
+     * @return The processed node.
+     */
+    protected AST quotedString(AST ident) {
+        return ident;
+    }
+
+    /**
+     * A check to see if the text of the given node represents a known function name.
+     *
+     * @param ast The node whose text we want to check.
+     *
+     * @return True if the node's text is a known function name, false otherwise.
+     *
+     * @see org.hibernate.dialect.function.SQLFunctionRegistry
+     */
+    protected boolean isFunctionName(AST ast) {
+        return false;
+    }
+
+    /**
+     * Process the given node as a function.
+     *
+     * @param The node representing the function invocation (including parameters as subtree components).
+     *
+     * @return The processed node.
+     */
+    protected AST resolveFunction(AST ast) {
+        return ast;
+    }
+
+    /**
+     * Process the given node as an IDENT.  May represent either a column reference or a property reference.
+     *
+     * @param ident The node whose text represents either a column or property reference.
+     *
+     * @return The processed node.
+     */
+    protected AST resolveIdent(AST ident) {
+        return ident;
+    }
+
+    /**
+     * Allow post processing of each <tt>sort specification</tt>
+     *
+     * @param The grammar-built sort specification subtree.
+     *
+     * @return The processed sort specification subtree.
+     */
+    protected AST postProcessSortSpecification(AST sortSpec) {
+        return sortSpec;
+    }
+
+}
+
+/**
+ * Main recognition rule for this grammar
+ */
+orderByFragment :
+    sortSpecification ( COMMA! sortSpecification  )* {
+        #orderByFragment = #( [ORDER_BY, "order-by"], #orderByFragment );
+    }
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>sort specification</tt>, which is essentially each thing upon which
+ * the results should be sorted.
+ */
+sortSpecification :
+    sortKey (collationSpecification)? (orderingSpecification)? {
+        #sortSpecification = #( [SORT_SPEC, "{sort specification}"], #sortSpecification );
+        #sortSpecification = postProcessSortSpecification( #sortSpecification );
+    }
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>sort key</tt> which is the expression (column, function, etc) upon
+ * which to base the sorting.
+ */
+sortKey! :
+    e:expression {
+        #sortKey = #( [SORT_KEY, "sort key"], #e );
+    }
+;
+
+/**
+ * Reconition rule what this grammar recognizes as valid <tt>sort key</tt>.
+ */
+expression! :
+    HARD_QUOTE qi:IDENT HARD_QUOTE {
+        #expression = quotedIdentifier( #qi );
+    }
+    | ( IDENT (DOT IDENT)* OPEN_PAREN ) => f:functionCall {
+        #expression = #f;
+    }
+    | p:simplePropertyPath {
+        #expression = resolveIdent( #p );
+    }
+    | i:IDENT {
+        if ( isFunctionName( #i ) ) {
+            #expression = resolveFunction( #i );
+        }
+        else {
+            #expression = resolveIdent( #i );
+        }
+    }
+;
+
+/**
+ * Intended for use as a syntactic predicate to determine whether an IDENT represents a known SQL function name.
+ */
+functionCallCheck! :
+    IDENT (DOT IDENT)* OPEN_PAREN { true }?
+;
+
+/**
+ * Recognition rule for a function call
+ */
+functionCall! :
+    fn:functionName OPEN_PAREN pl:functionParameterList CLOSE_PAREN {
+        #functionCall = #( [IDENT, extractText( #fn )], #pl );
+        #functionCall = resolveFunction( #functionCall );
+    }
+;
+
+/**
+ * A function-name is an IDENT followed by zero or more (DOT IDENT) sequences
+ */
+functionName {
+        StringBuffer buffer = new StringBuffer();
+    }
+    : i:IDENT { buffer.append( i.getText() ); }
+            ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )* {
+        #functionName = #( [IDENT,buffer.toString()] );
+    }
+    ;
+
+/**
+ * Recognition rule used to "wrap" all function parameters into an EXPR_LIST node
+ */
+functionParameterList :
+    functionParameter ( COMMA! functionParameter )* {
+        #functionParameterList = #( [EXPR_LIST, "{param list}"], #functionParameterList );
+    }
+;
+
+/**
+ * Recognized function parameters.
+ */
+functionParameter :
+    expression
+    | NUM_DOUBLE
+    | NUM_FLOAT
+    | NUM_INT
+    | NUM_LONG
+    | QUOTED_STRING {
+        #functionParameter = quotedString( #functionParameter );
+    }
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>collation specification</tt> used to allow specifying that sorting for
+ * the given {@link #sortSpecification} be treated within a specific character-set.
+ */
+collationSpecification! :
+    c:COLLATE cn:collationName {
+        #collationSpecification = #( [COLLATE, extractText( #cn )] );
+    }
+;
+
+/**
+ * The collation name wrt {@link #collationSpecification}.  Namely, the character-set.
+ */
+collationName :
+    IDENT
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>ordering specification</tt>; <tt>ASCENDING</tt> or
+ * <tt>DESCENDING</tt>.
+ */
+orderingSpecification! :
+    ( "asc" | "ascending" ) {
+        #orderingSpecification = #( [ORDER_SPEC, "asc"] );
+    }
+    | ( "desc" | "descending") {
+        #orderingSpecification = #( [ORDER_SPEC, "desc"] );
+    }
+;
+
+/**
+ * A simple-property-path is an IDENT followed by one or more (DOT IDENT) sequences
+ */
+simplePropertyPath {
+        StringBuffer buffer = new StringBuffer();
+    }
+    : i:IDENT { buffer.append( i.getText() ); }
+            ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )+ {
+        #simplePropertyPath = #( [IDENT,buffer.toString()] );
+    }
+;
+
+
+// **** LEXER ******************************************************************
+
+/**
+ * Lexer for the <tt>order-by</tt> fragment parser
+
+ * @author Steve Ebersole
+ * @author Joshua Davis
+ */
+class GeneratedOrderByLexer extends Lexer;
+
+options {
+	exportVocab=OrderByTemplate;
+	testLiterals = false;
+	k=2;
+	charVocabulary='\u0000'..'\uFFFE';	// Allow any char but \uFFFF (16 bit -1, ANTLR's EOF character)
+	caseSensitive = false;
+	caseSensitiveLiterals = false;
+}
+
+// -- Keywords --
+
+OPEN_PAREN: '(';
+CLOSE_PAREN: ')';
+
+COMMA: ',';
+
+HARD_QUOTE: '`';
+
+IDENT options { testLiterals=true; }
+	: ID_START_LETTER ( ID_LETTER )*
+	;
+
+protected
+ID_START_LETTER
+    :    '_'
+    |    '$'
+    |    'a'..'z'
+    |    '\u0080'..'\ufffe'       // HHH-558 : Allow unicode chars in identifiers
+    ;
+
+protected
+ID_LETTER
+    :    ID_START_LETTER
+    |    '0'..'9'
+    ;
+
+QUOTED_STRING
+	  : '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''
+	;
+
+protected
+ESCqs
+	:
+		'\'' '\''
+	;
+
+//--- From the Java example grammar ---
+// a numeric literal
+NUM_INT
+	{boolean isDecimal=false; Token t=null;}
+	:   '.' {_ttype = DOT;}
+			(	('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
+				{
+					if (t != null && t.getText().toUpperCase().indexOf('F')>=0)
+					{
+						_ttype = NUM_FLOAT;
+					}
+					else
+					{
+						_ttype = NUM_DOUBLE; // assume double
+					}
+				}
+			)?
+	|	(	'0' {isDecimal = true;} // special case for just '0'
+			(	('x')
+				(											// hex
+					// the 'e'|'E' and float suffix stuff look
+					// like hex digits, hence the (...)+ doesn't
+					// know when to stop: ambig.  ANTLR resolves
+					// it correctly by matching immediately.  It
+					// is therefore ok to hush warning.
+					options { warnWhenFollowAmbig=false; }
+				:	HEX_DIGIT
+				)+
+			|	('0'..'7')+									// octal
+			)?
+		|	('1'..'9') ('0'..'9')*  {isDecimal=true;}		// non-zero decimal
+		)
+		(	('l') { _ttype = NUM_LONG; }
+
+		// only check to see if it's a float if looks like decimal so far
+		|	{isDecimal}?
+			(   '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
+			|   EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
+			|   f4:FLOAT_SUFFIX {t=f4;}
+			)
+			{
+				if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0)
+				{
+					_ttype = NUM_FLOAT;
+				}
+				else
+				{
+					_ttype = NUM_DOUBLE; // assume double
+				}
+			}
+		)?
+	;
+
+// hexadecimal digit (again, note it's protected!)
+protected
+HEX_DIGIT
+	:	('0'..'9'|'a'..'f')
+	;
+
+// a couple protected methods to assist in matching floating point numbers
+protected
+EXPONENT
+	:	('e') ('+'|'-')? ('0'..'9')+
+	;
+
+protected
+FLOAT_SUFFIX
+	:	'f'|'d'
+	;
+
+WS  :   (   ' '
+		|   '\t'
+		|   '\r' '\n' { newline(); }
+		|   '\n'      { newline(); }
+		|   '\r'      { newline(); }
+		)
+		{$setType(Token.SKIP);} //ignore this token
+	;

Copied: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,88 @@
+header
+{
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+}
+/**
+ * Antlr grammar for rendering <tt>ORDER_BY</tt> trees as described by the {@link OrderByFragmentParser}
+ *
+ * @author Steve Ebersole
+ */
+class GeneratedOrderByFragmentRenderer extends TreeParser;
+
+options {
+	importVocab=OrderByTemplate;
+	buildAST=false;
+}
+
+{
+    // the buffer to which we write the resulting SQL.
+	private StringBuffer buffer = new StringBuffer();
+
+	protected void out(String text) {
+	    buffer.append( text );
+	}
+
+	protected void out(AST ast) {
+	    buffer.append( ast.getText() );
+	}
+
+    /*package*/ String getRenderedFragment() {
+        return buffer.toString();
+    }
+}
+
+orderByFragment :
+    #( ORDER_BY sortSpecification ( {out(", ");} sortSpecification)* )
+;
+
+sortSpecification :
+    #( SORT_SPEC sortKeySpecification (collationSpecification)? (orderingSpecification)? )
+;
+
+sortKeySpecification :
+    #( SORT_KEY sortKey )
+;
+
+sortKey :
+    i:IDENT {
+        out( #i );
+    }
+;
+
+collationSpecification :
+    c:COLLATE {
+        out( " collate " );
+        out( c );
+    }
+;
+
+orderingSpecification :
+    o:ORDER_SPEC {
+        out( " " );
+        out( #o );
+    }
+;
\ No newline at end of file

Deleted: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g	2009-01-06 20:11:13 UTC (rev 15747)
@@ -1,92 +0,0 @@
-header
-{
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors.  All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA  02110-1301  USA
- *
- */
-package org.hibernate.sql.ordering.antlr;
-}
-/**
- * Antlr grammar for rendering <tt>ORDER_BY</tt> trees as described by the {@link OrderByFragmentParser}
-
- * @author Steve Ebersole
- */
-class GeneratedOrderByFragmentRenderer extends TreeParser;
-
-options {
-	importVocab=OrderByTemplate;
-	buildAST=false;
-}
-
-{
-    // the buffer to which we write the resulting SQL.
-	private StringBuffer buffer = new StringBuffer();
-
-	protected void out(String text) {
-	    buffer.append( text );
-	}
-
-	protected void out(AST ast) {
-	    buffer.append( ast.getText() );
-	}
-
-    /*package*/ String getRenderedFragment() {
-        return buffer.toString();
-    }
-}
-
-orderByFragment
-    : #(
-        ORDER_BY sortSpecification ( {out(", ");} sortSpecification)*
-    )
-    ;
-
-sortSpecification
-    : #(
-        SORT_SPEC sortKeySpecification (collationSpecification)? (orderingSpecification)?
-    )
-    ;
-
-sortKeySpecification
-    : #(SORT_KEY sortKey)
-    ;
-
-sortKey
-    : i:IDENT {
-        out( #i );
-    }
-    ;
-
-collationSpecification
-    : c:COLLATE {
-        out( " collate " );
-        out( c );
-    }
-    ;
-
-orderingSpecification
-    : o:ORDER_SPEC {
-        out( " " );
-        out( #o );
-    }
-    ;
\ No newline at end of file

Deleted: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g	2009-01-06 20:11:13 UTC (rev 15747)
@@ -1,440 +0,0 @@
-header
-{
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors.  All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA  02110-1301  USA
- *
- */
-package org.hibernate.sql.ordering.antlr;
-}
-/**
- * Antlr grammar for dealing with <tt>order-by</tt> mapping fragments.
-
- * @author Steve Ebersole
- */
-class GeneratedOrderByFragmentParser extends Parser;
-
-options
-{
-	exportVocab=OrderByTemplate;
-	buildAST=true;
-	k=3;
-}
-
-tokens
-{
-    // synthetic tokens
-    ORDER_BY;
-    SORT_SPEC;
-    ORDER_SPEC;
-    SORT_KEY;
-    EXPR_LIST;
-    DOT;
-    IDENT_LIST;
-    COLUMN_REF;
-
-    COLLATE="collate";
-	ASCENDING="asc";
-	DESCENDING="desc";
-}
-
-
-{
-    /**
-     * Method for logging execution trace information.
-     *
-     * @param msg The trace message.
-     */
-    protected void trace(String msg) {
-        System.out.println( msg );
-    }
-
-    /**
-     * Extract a node's text.
-     *
-     * @param ast The node
-     *
-     * @return The text.
-     */
-    protected final String extractText(AST ast) {
-        // for some reason, within AST creation blocks "[]" I am somtimes unable to refer to the AST.getText() method
-        // using #var (the #var is not interpreted as the rule's output AST).
-        return ast.getText();
-    }
-
-    /**
-     * Process the given node as a quote identifier.  These need to be quoted in the dialect-specific way.
-     *
-     * @param ident The quoted-identifier node.
-     *
-     * @return The processed node.
-     *
-     * @see org.hibernate.dialect.Dialect#quote
-     */
-    protected AST quotedIdentifier(AST ident) {
-        return ident;
-    }
-
-    /**
-     * Process the given node as a quote string.
-     *
-     * @param ident The quoted string.  This is used from within function param recognition, and represents a
-     * SQL-quoted string.
-     *
-     * @return The processed node.
-     */
-    protected AST quotedString(AST ident) {
-        return ident;
-    }
-
-    /**
-     * A check to see if the text of the given node represents a known function name.
-     *
-     * @param ast The node whose text we want to check.
-     *
-     * @return True if the node's text is a known function name, false otherwise.
-     *
-     * @see org.hibernate.dialect.function.SQLFunctionRegistry
-     */
-    protected boolean isFunctionName(AST ast) {
-        return false;
-    }
-
-    /**
-     * Process the given node as a function.
-     *
-     * @param The node representing the function invocation (including parameters as subtree components).
-     *
-     * @return The processed node.
-     */
-    protected AST resolveFunction(AST ast) {
-        return ast;
-    }
-
-    /**
-     * Process the given node as an IDENT.  May represent either a column reference or a property reference.
-     *
-     * @param ident The node whose text represents either a column or property reference.
-     *
-     * @return The processed node.
-     */
-    protected AST resolveIdent(AST ident) {
-        return ident;
-    }
-
-    /**
-     * Allow post processing of each <tt>sort specification</tt>
-     *
-     * @param The grammar-built sort specification subtree.
-     *
-     * @return The processed sort specification subtree.
-     */
-    protected AST postProcessSortSpecification(AST sortSpec) {
-        return sortSpec;
-    }
-
-}
-
-/**
- * Main recognition rule for this grammar
- */
-orderByFragment { trace("orderByFragment"); }
-    : sortSpecification ( COMMA! sortSpecification  )* {
-        #orderByFragment = #( [ORDER_BY, "order-by"], #orderByFragment );
-    }
-    ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>sort specification</tt>, which is essentially each thing upon which
- * the results should be sorted.
- */
-sortSpecification { trace("sortSpecification"); }
-    : sortKey (collationSpecification)? (orderingSpecification)? {
-        #sortSpecification = #( [SORT_SPEC, "{sort specification}"], #sortSpecification );
-        #sortSpecification = postProcessSortSpecification( #sortSpecification );
-    }
-    ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>sort key</tt> which is the expression (column, function, etc) upon
- * which to base the sorting.
- */
-sortKey! { trace("sortKey"); }
-    : e:expression {
-        #sortKey = #( [SORT_KEY, "sort key"], #e );
-    }
-    ;
-
-/**
- * Reconition rule what this grammar recognizes as valid <tt>sort key</tt>.
- */
-expression! { trace("expression"); }
-    : HARD_QUOTE qi:IDENT HARD_QUOTE {
-        #expression = quotedIdentifier( #qi );
-    }
-    | ( IDENT (DOT IDENT)* OPEN_PAREN ) => f:functionCall {
-        #expression = #f;
-    }
-    | p:simplePropertyPath {
-        #expression = resolveIdent( #p );
-    }
-    | i:IDENT {
-        if ( isFunctionName( #i ) ) {
-            #expression = resolveFunction( #i );
-        }
-        else {
-            #expression = resolveIdent( #i );
-        }
-    }
-    ;
-
-/**
- * Intended for use as a syntactic predicate to determine whether an IDENT represents a known SQL function name.
- */
-functionCallCheck! { trace("functionCallCheck"); }
-    : IDENT (DOT IDENT)* OPEN_PAREN { true }?
-    ;
-
-/**
- * Recognition rule for a function call
- */
-functionCall! { trace("functionCall"); }
-    : fn:functionName OPEN_PAREN pl:functionParameterList CLOSE_PAREN {
-        #functionCall = #( [IDENT, extractText( #fn )], #pl );
-        #functionCall = resolveFunction( #functionCall );
-    }
-    ;
-
-/**
- * A function-name is an IDENT followed by zero or more (DOT IDENT) sequences
- */
-functionName {
-        trace("functionName");
-        StringBuffer buffer = new StringBuffer();
-    }
-    : i:IDENT { buffer.append( i.getText() ); }
-            ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )* {
-        #functionName = #( [IDENT,buffer.toString()] );
-    }
-    ;
-
-/**
- * Recognition rule used to "wrap" all function parameters into an EXPR_LIST node
- */
-functionParameterList { trace("functionParameterList"); }
-    : functionParameter ( COMMA! functionParameter )* {
-        #functionParameterList = #( [EXPR_LIST, "{param list}"], #functionParameterList );
-    }
-    ;
-
-/**
- * Recognized function parameters.
- */
-functionParameter { trace("functionParameter"); }
-    : expression
-    | NUM_DOUBLE
-    | NUM_FLOAT
-    | NUM_INT
-    | NUM_LONG
-    | QUOTED_STRING {
-        #functionParameter = quotedString( #functionParameter );
-    }
-    ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>collation specification</tt> used to allow specifying that sorting for
- * the given {@link #sortSpecification} be treated within a specific character-set.
- */
-collationSpecification! { trace("collationSpecification"); }
-    : c:COLLATE cn:collationName {
-        #collationSpecification = #( [COLLATE, extractText( #cn )] );
-    }
-    ;
-
-/**
- * The collation name wrt {@link #collationSpecification}.  Namely, the character-set.
- */
-collationName { trace("collationSpecification"); }
-    : IDENT
-    ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>ordering specification</tt>; <tt>ASCENDING</tt> or
- * <tt>DESCENDING</tt>.
- */
-orderingSpecification! { trace("orderingSpecification"); }
-    : ( "asc" | "ascending" ) {
-        #orderingSpecification = #( [ORDER_SPEC, "asc"] );
-    }
-    | ( "desc" | "descending") {
-        #orderingSpecification = #( [ORDER_SPEC, "desc"] );
-    }
-    ;
-
-/**
- * A simple-property-path is an IDENT followed by one or more (DOT IDENT) sequences
- */
-simplePropertyPath {
-        trace("simplePropertyPath");
-        StringBuffer buffer = new StringBuffer();
-    }
-    : i:IDENT { buffer.append( i.getText() ); }
-            ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )+ {
-        #simplePropertyPath = #( [IDENT,buffer.toString()] );
-    }
-    ;
-
-
-// **** LEXER ******************************************************************
-
-/**
- * Lexer for the <tt>order-by</tt> fragment parser
-
- * @author Steve Ebersole
- * @author Joshua Davis
- */
-class GeneratedOrderByLexer extends Lexer;
-
-options {
-	exportVocab=OrderByTemplate;
-	testLiterals = false;
-	k=2;
-	charVocabulary='\u0000'..'\uFFFE';	// Allow any char but \uFFFF (16 bit -1, ANTLR's EOF character)
-	caseSensitive = false;
-	caseSensitiveLiterals = false;
-}
-
-// -- Keywords --
-
-OPEN_PAREN: '(';
-CLOSE_PAREN: ')';
-
-COMMA: ',';
-
-HARD_QUOTE: '`';
-
-IDENT options { testLiterals=true; }
-	: ID_START_LETTER ( ID_LETTER )*
-	;
-
-protected
-ID_START_LETTER
-    :    '_'
-    |    '$'
-    |    'a'..'z'
-    |    '\u0080'..'\ufffe'       // HHH-558 : Allow unicode chars in identifiers
-    ;
-
-protected
-ID_LETTER
-    :    ID_START_LETTER
-    |    '0'..'9'
-    ;
-
-QUOTED_STRING
-	  : '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''
-	;
-
-protected
-ESCqs
-	:
-		'\'' '\''
-	;
-
-//--- From the Java example grammar ---
-// a numeric literal
-NUM_INT
-	{boolean isDecimal=false; Token t=null;}
-	:   '.' {_ttype = DOT;}
-			(	('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
-				{
-					if (t != null && t.getText().toUpperCase().indexOf('F')>=0)
-					{
-						_ttype = NUM_FLOAT;
-					}
-					else
-					{
-						_ttype = NUM_DOUBLE; // assume double
-					}
-				}
-			)?
-	|	(	'0' {isDecimal = true;} // special case for just '0'
-			(	('x')
-				(											// hex
-					// the 'e'|'E' and float suffix stuff look
-					// like hex digits, hence the (...)+ doesn't
-					// know when to stop: ambig.  ANTLR resolves
-					// it correctly by matching immediately.  It
-					// is therefore ok to hush warning.
-					options { warnWhenFollowAmbig=false; }
-				:	HEX_DIGIT
-				)+
-			|	('0'..'7')+									// octal
-			)?
-		|	('1'..'9') ('0'..'9')*  {isDecimal=true;}		// non-zero decimal
-		)
-		(	('l') { _ttype = NUM_LONG; }
-
-		// only check to see if it's a float if looks like decimal so far
-		|	{isDecimal}?
-			(   '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
-			|   EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
-			|   f4:FLOAT_SUFFIX {t=f4;}
-			)
-			{
-				if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0)
-				{
-					_ttype = NUM_FLOAT;
-				}
-				else
-				{
-					_ttype = NUM_DOUBLE; // assume double
-				}
-			}
-		)?
-	;
-
-// hexadecimal digit (again, note it's protected!)
-protected
-HEX_DIGIT
-	:	('0'..'9'|'a'..'f')
-	;
-
-// a couple protected methods to assist in matching floating point numbers
-protected
-EXPONENT
-	:	('e') ('+'|'-')? ('0'..'9')+
-	;
-
-protected
-FLOAT_SUFFIX
-	:	'f'|'d'
-	;
-
-WS  :   (   ' '
-		|   '\t'
-		|   '\r' '\n' { newline(); }
-		|   '\n'      { newline(); }
-		|   '\r'      { newline(); }
-		)
-		{$setType(Token.SKIP);} //ignore this token
-	;

Modified: core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g	2009-01-06 20:11:13 UTC (rev 15747)
@@ -74,7 +74,7 @@
     BIT = "bit";
     BIT_LENGTH = "bit_lenght";
     BOTH = "both";
-    BY = "by";
+//    BY = "by";
     CASE = "case";
     CAST = "cast";
     CHAR = "char";
@@ -112,7 +112,7 @@
     FROM = "from";
     FULL = "full";
     GLOBAL = "global";
-    GROUP = "group";
+//    GROUP = "group";
     HAVING = "having";
     HOUR = "hour";
     IN = "in";
@@ -150,7 +150,7 @@
     ON = "on";
     ONLY = "only";
     OR = "or";
-    ORDER = "order";
+//    ORDER = "order";
 	OUTER = "outer";
 	OVERLAPS = "overlaps";
 	PARTIAL = "partial";
@@ -194,6 +194,8 @@
     ZONE = "zone";
 
     DOT;
+    ORDER_BY;
+    GROUP_BY;
 
     // synthetic numeric literal types
     NUM_INT_LITERAL;
@@ -246,10 +248,81 @@
 	}
 }
 
-noRules :
+protected
+literal :
+    numericLiteral
+    | characterLiteral
+    | dateLiteral
+    | timeLiteral
+    | timestampLiteral
+    | intervalLiteral
 ;
 
+protected
+numericLiteral :
+    UNSIGNED_INTEGER
+    | NUM_INT_LITERAL
+    | NUM_LONG_LITERAL
+    | NUM_DOUBLE_LITERAL
+    | NUM_FLOAT_LITERAL
+;
 
+protected
+characterLiteral :
+    CHAR_STRING
+    | NATIONAL_CHAR_STRING_LIT
+	| BIT_STRING_LIT
+	| HEX_STRING_LIT
+;
+
+protected
+dateLiteral :
+    DATE^ CHAR_STRING
+;
+
+protected
+timeLiteral :
+    TIME^ CHAR_STRING
+;
+
+protected
+timestampLiteral :
+    TIMESTAMP^ CHAR_STRING
+;
+
+protected
+intervalLiteral :
+    INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier
+;
+
+protected
+intervalQualifier :
+    intervalStartField ( TO intervalEndField | )
+    | SECOND ( LEFT_PAREN UNSIGNED_INTEGER ( COMMA UNSIGNED_INTEGER )? RIGHT_PAREN )?
+;
+
+protected
+intervalStartField :
+    nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+;
+
+protected
+intervalEndField :
+    nonSecondDatetimeField
+	| SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+;
+
+protected
+nonSecondDatetimeField :
+    YEAR
+    | MONTH
+    | DAY
+    | HOUR
+    | MINUTE
+;
+
+
+
 // Lexer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 /**
@@ -349,9 +422,16 @@
 	    | BIT_STRING_LIT {$setType(BIT_STRING_LIT);}
 	    | HEX_STRING_LIT {$setType(HEX_STRING_LIT);}
 	)
-	| (SIMPLE_LETTER | '_' | '$') (SIMPLE_LETTER | '_' | '$' | '0'..'9')* {
+	| id:ID { setPossibleIdentifier( true ); } (
+	    { id.getText().equalsIgnoreCase("order") }? (WHITESPACE)+ "by"! { setPossibleIdentifier( false ); $setType(ORDER_BY); $setText("order by"); }
+	    | { id.getText().equalsIgnoreCase("group") }? (WHITESPACE)+ "by"! { setPossibleIdentifier( false ); $setType(GROUP_BY); $setText("group by"); }
+	)?
+;
+
+protected
+ID options { testLiterals=true; } :
+	(SIMPLE_LETTER | '_' | '$') (SIMPLE_LETTER | '_' | '$' | '0'..'9')* {
         setPossibleIdentifier( true );
-//	    $setType( testLiteralsTable( IDENT ) );
 	}
 ;
 

Deleted: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -1,42 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors.  All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA  02110-1301  USA
- */
-package org.hibernate.hql.ast.phase.parse;
-
-import antlr.ASTFactory;
-
-import org.hibernate.sql.ast.common.Node;
-
-/**
- * TODO : javadoc
- *
- * @author Steve Ebersole
- */
-public class ASTFactoryImpl extends ASTFactory {
-	/**
-	 * {@inheritDoc}
-	 */
-	public Class getASTNodeType(int tokenType) {
-		return Node.class;
-	}
-}

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -80,7 +80,7 @@
 import org.hibernate.sql.SelectFragment;
 import org.hibernate.sql.SimpleSelect;
 import org.hibernate.sql.Template;
-import org.hibernate.sql.ordering.antlr.ColumnMapper;
+import org.hibernate.sql.ast.ordering.ColumnMapper;
 import org.hibernate.type.AbstractComponentType;
 import org.hibernate.type.CollectionType;
 import org.hibernate.type.EntityType;

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -30,9 +30,9 @@
 import org.hibernate.dialect.Dialect;
 import org.hibernate.dialect.function.SQLFunctionRegistry;
 import org.hibernate.util.StringHelper;
-import org.hibernate.sql.ordering.antlr.ColumnMapper;
-import org.hibernate.sql.ordering.antlr.TranslationContext;
-import org.hibernate.sql.ordering.antlr.OrderByFragmentTranslator;
+import org.hibernate.sql.ast.ordering.ColumnMapper;
+import org.hibernate.sql.ast.ordering.TranslationContext;
+import org.hibernate.sql.ast.ordering.OrderByFragmentTranslator;
 import org.hibernate.engine.SessionFactoryImplementor;
 
 /**

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -1,36 +1,79 @@
-// $Id: DetailedSemanticException.java 5690 2005-02-12 20:27:50Z pgmjsd $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
 package org.hibernate.sql.ast;
 
 import antlr.SemanticException;
+import antlr.Token;
+import antlr.collections.AST;
 
 import java.io.PrintStream;
 import java.io.PrintWriter;
 
 /**
- * Thrown when a call to the underlying Hibernate engine fails, indicating
- * some form of semantic exception (e.g. a class name was not found in the
- * current mappings, etc.).
+ * Thrown when a call to the underlying Hibernate engine fails, indicating some form of semantic exception (e.g. an
+ * entity name was not found in the mappings, etc.).
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
  */
 public class DetailedSemanticException extends SemanticException {
 	private Throwable cause;
-	private boolean showCauseMessage = true;
 
 	public DetailedSemanticException(String message) {
 		super( message );
 	}
 
-	public DetailedSemanticException(String s, Throwable e) {
-		super( s );
+	public DetailedSemanticException(String message, Token token) {
+		super( message, token.getFilename(), token.getLine(), token.getColumn() );
+	}
+
+	public DetailedSemanticException(String message, AST ast) {
+		super( message, "", ast.getLine(), ast.getColumn() );
+	}
+
+	public DetailedSemanticException(String message, Throwable e) {
+		this( message );
 		cause = e;
 	}
 
+	public DetailedSemanticException(String message, Token token, Throwable e) {
+		this( message, token );
+		cause = e;
+	}
+
+	public DetailedSemanticException(String message, AST ast, Throwable e) {
+		this( message, ast );
+		cause = e;
+	}
+
 	/**
 	 * Converts everything to a string.
 	 *
 	 * @return a string.
 	 */
 	public String toString() {
-		if ( cause == null || ( !showCauseMessage ) ) {
+		if ( cause == null ) {
 			return super.toString();
 		}
 		else {

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -3,6 +3,8 @@
 import java.io.Serializable;
 import java.util.HashMap;
 
+import org.hibernate.sql.ast.util.ASTUtil;
+
 /**
  * Represents a canonical join type.
  * <p/>
@@ -59,4 +61,26 @@
 	private Object readResolve() {
 		return INSTANCES.get( name );
 	}
+
+	public static JoinType resolve(Node node) {
+		switch ( node.getType() ) {
+			case Sql92TokenTypes.INNER :
+				return JoinType.INNER;
+			case Sql92TokenTypes.LEFT :
+				return JoinType.LEFT;
+			case Sql92TokenTypes.RIGHT :
+				return JoinType.RIGHT;
+			case Sql92TokenTypes.CROSS :
+				return JoinType.CROSS;
+			case Sql92TokenTypes.FULL :
+				return JoinType.FULL;
+			default :
+				throw new IllegalArgumentException(
+						"Cannot resolve join-type node [type=" +
+								ASTUtil.getTokenTypeName( Sql92TokenTypes.class, node.getType() ) +
+								", text=" + node.getText() +
+								"]"
+				);
+		}
+	}
 }

Deleted: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -1,92 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors.  All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA  02110-1301  USA
- */
-package org.hibernate.sql.ast.common;
-
-import antlr.Token;
-import antlr.collections.AST;
-
-/**
- * Basic AST node
- *
- * @author Joshua Davis
- * @author Steve Ebersole
- */
-public class Node extends antlr.CommonAST {
-	private String filename;
-	private int line;
-	private int column;
-
-	public Node() {
-		super();
-	}
-
-	public Node(Token tok) {
-		super( tok );  // NOTE: This will call initialize(tok)!
-	}
-
-	public void initialize(Token token) {
-		super.initialize( token );
-		// Propagate line/column information from the lexer during
-		// stream parsing.
-		filename = token.getFilename();
-		line = token.getLine();
-		column = token.getColumn();
-	}
-
-	public void initialize(AST ast) {
-		super.initialize( ast );
-		if ( ast instanceof Node ) {
-			// Propagate line/column information from the source AST during tree walking.
-			transferTrackingInfo( ( Node ) ast );
-		}
-	}
-
-	public void transferTrackingInfo(AST ast) {
-		if ( ast instanceof Node ) {
-			transferTrackingInfo( ( Node ) ast );
-		}
-		else {
-			line = ast.getLine();
-			column = ast.getColumn();
-		}
-	}
-
-	public void transferTrackingInfo(Node node) {
-		filename = node.filename;
-		line = node.line;
-		column = node.column;
-	}
-
-	public String getFilename() {
-		return filename;
-	}
-
-	public int getLine() {
-		return line;
-	}
-
-	public int getColumn() {
-		return column;
-	}
-}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,104 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.common;
+
+import antlr.Token;
+import antlr.collections.AST;
+
+/**
+ * Basic AST node
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class Node extends antlr.CommonAST {
+	private String filename;
+	private int line;
+	private int column;
+
+	public Node() {
+		super();
+	}
+
+	public Node(Token tok) {
+		super( tok );  // NOTE: This will call initialize(tok)!
+	}
+
+	/**
+	 * Retrieve the textual representation of a node to be used in the resulting sql.
+	 * <p/>
+	 * This is intended for subclasses to override to allow certain nodes to provide their own renderable representation
+	 * instead of the default {@link antlr.collections.AST#getText()}.
+	 *
+	 * @return The renderable text.
+	 */
+	public String getRenderableText() {
+		return getText();
+	}
+
+	public void initialize(Token token) {
+		super.initialize( token );
+		// Propagate line/column information from the lexer during
+		// stream parsing.
+		filename = token.getFilename();
+		line = token.getLine();
+		column = token.getColumn();
+	}
+
+	public void initialize(AST ast) {
+		super.initialize( ast );
+		if ( ast instanceof Node ) {
+			// Propagate line/column information from the source AST during tree walking.
+			transferTrackingInfo( ( Node ) ast );
+		}
+	}
+
+	public void transferTrackingInfo(AST ast) {
+		if ( ast instanceof Node ) {
+			transferTrackingInfo( ( Node ) ast );
+		}
+		else {
+			line = ast.getLine();
+			column = ast.getColumn();
+		}
+	}
+
+	public void transferTrackingInfo(Node node) {
+		filename = node.filename;
+		line = node.line;
+		column = node.column;
+	}
+
+	public String getFilename() {
+		return filename;
+	}
+
+	public int getLine() {
+		return line;
+	}
+
+	public int getColumn() {
+		return column;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.common;
+
+import antlr.ASTFactory;
+
+/**
+ * An {@link ASTFactory} which includes line/column tracking information into its generated
+ * {@link antlr.collections.AST nodes}.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class NodeFactory extends ASTFactory {
+	/**
+	 * Determine the default {@link antlr.collections.AST node} class to use.  Used from within
+	 * {@link #getASTNodeType(int)} when no specific  override is defined/needed for a particular token type.
+	 *
+	 * @return The default {@link antlr.collections.AST node} class to use
+	 */
+	protected Class determineDefaultNodeClass() {
+		return Node.class;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Class getASTNodeType(int tokenType) {
+		return determineDefaultNodeClass();
+	}
+}

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -26,7 +26,7 @@
 import org.hibernate.HibernateException;
 
 /**
- * Thrown to indicate a panic situation ossuring in a lexer.
+ * Thrown to indicate a panic situation occuring in a lexer.
  *
  * @author Steve Ebersole
  */

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/CollationSpecification.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,36 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models a collation specification (<tt>COLLATE</tt> using a specific character-set) within a
+ * {@link SortSpecification}.
+ *
+ * @author Steve Ebersole
+ */
+public class CollationSpecification extends Node {
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/ColumnMapper.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Contract for mapping a (an assumed) property reference to its columns.
+ *
+ * @author Steve Ebersole
+ */
+public interface ColumnMapper {
+	/**
+	 * Resolve the property reference to its underlying columns.
+	 *
+	 * @param reference The property reference name.
+	 *
+	 * @return The underlying columns, or null if the property reference is unknown.
+	 *
+	 * @throws HibernateException Generally indicates that the property reference is unkown; interpretation is the
+	 * same as a null return.
+	 */
+	public String[] map(String reference) throws HibernateException;
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/Factory.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.NodeFactory;
+
+/**
+ * Acts as a {@link NodeFactory} for injecting our specific AST node classes into the Antlr generated trees.
+ *
+ * @author Steve Ebersole
+ */
+public class Factory extends NodeFactory implements OrderByTemplateTokenTypes {
+	/**
+	 * {@inheritDoc}
+	 */
+	public Class getASTNodeType(int i) {
+		switch ( i ) {
+			case ORDER_BY:
+				return OrderByFragment.class;
+			case SORT_SPEC:
+				return SortSpecification.class;
+			case ORDER_SPEC:
+				return OrderingSpecification.class;
+			case COLLATE:
+				return CollationSpecification.class;
+			case SORT_KEY:
+				return SortKey.class;
+			default:
+				return Node.class;
+		}
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragment.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Represents a parsed <tt>order-by</tt> mapping fragment.  This holds the tree of all {@link SortSpecification}s.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragment extends Node {
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,214 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import java.util.ArrayList;
+
+import antlr.TokenStream;
+import antlr.CommonAST;
+import antlr.TokenStreamException;
+import antlr.collections.AST;
+
+import org.hibernate.sql.Template;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extension of the Antlr-generated parser for the purpose of adding our custom parsing behavior.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentParser extends GeneratedOrderByFragmentParser {
+	private static final Logger log = LoggerFactory.getLogger( OrderByFragmentParser.class );
+
+	private final TranslationContext context;
+	private int traceDepth = 0;
+
+	public OrderByFragmentParser(TokenStream lexer, TranslationContext context) {
+		super( lexer );
+		super.setASTFactory( new Factory() );
+		this.context = context;
+	}
+
+
+	// handle trace logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void traceIn(String ruleName) throws TokenStreamException {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = StringHelper.repeat( "-", (traceDepth++ * 2) ) + "->";
+		trace( prefix + ruleName );
+	}
+
+	public void traceOut(String ruleName) throws TokenStreamException {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = "<-" + StringHelper.repeat( "-", (--traceDepth * 2) );
+		trace( prefix + ruleName );
+	}
+
+    private void trace(String msg) {
+		log.trace( msg );
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected AST quotedIdentifier(AST ident) {
+		return getASTFactory().create(
+				IDENT,
+				Template.TEMPLATE + "." + context.getDialect().quote( '`' + ident.getText() + '`' )
+		);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected AST quotedString(AST ident) {
+		return getASTFactory().create( IDENT, context.getDialect().quote( ident.getText() ) );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected boolean isFunctionName(AST ast) {
+		return context.getSqlFunctionRegistry().hasFunction( ast.getText() );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected AST resolveFunction(AST ast) {
+		AST child = ast.getFirstChild();
+		assert "{param list}".equals(  child.getText() );
+		child = child.getFirstChild();
+
+		final String functionName = ast.getText();
+		final SQLFunction function = context.getSqlFunctionRegistry().findSQLFunction( functionName );
+		if ( function == null ) {
+			String text = functionName;
+			if ( child != null ) {
+				text += '(';
+				while ( child != null ) {
+					text += child.getText();
+					child = child.getNextSibling();
+					if ( child != null ) {
+						text += ", ";
+					}
+				}
+				text += ')';
+			}
+			return getASTFactory().create( IDENT, text );
+		}
+		else {
+			ArrayList expressions = new ArrayList();
+			while ( child != null ) {
+				expressions.add( child.getText() );
+				child = child.getNextSibling();
+			}
+			final String text = function.render( expressions, context.getSessionFactory() );
+			return getASTFactory().create( IDENT, text );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected AST resolveIdent(AST ident) {
+		String text = ident.getText();
+		String[] replacements;
+		try {
+			replacements = context.getColumnMapper().map( text );
+		}
+		catch( Throwable t ) {
+			replacements = null;
+		}
+
+		if ( replacements == null || replacements.length == 0 ) {
+			return getASTFactory().create( IDENT, Template.TEMPLATE + "." + text );
+		}
+		else if ( replacements.length == 1 ) {
+			return getASTFactory().create( IDENT, Template.TEMPLATE + "." + replacements[0] );
+		}
+		else {
+			final AST root = getASTFactory().create( IDENT_LIST, "{ident list}" );
+			for ( int i = 0; i < replacements.length; i++ ) {
+				final String identText = Template.TEMPLATE + '.' + replacements[i];
+				root.addChild( getASTFactory().create( IDENT, identText ) );
+			}
+			return root;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected AST postProcessSortSpecification(AST sortSpec) {
+		assert SORT_SPEC == sortSpec.getType();
+		SortSpecification sortSpecification = ( SortSpecification ) sortSpec;
+		AST sortKey = sortSpecification.getSortKey();
+		if ( IDENT_LIST == sortKey.getFirstChild().getType() ) {
+			AST identList = sortKey.getFirstChild();
+			AST ident = identList.getFirstChild();
+			AST holder = new CommonAST();
+			do {
+				holder.addChild(
+						createSortSpecification(
+								ident,
+								sortSpecification.getCollation(),
+								sortSpecification.getOrdering()
+						)
+				);
+				ident = ident.getNextSibling();
+			} while ( ident != null );
+			sortSpec = holder.getFirstChild();
+		}
+		return sortSpec;
+	}
+
+	private SortSpecification createSortSpecification(
+			AST ident,
+			CollationSpecification collationSpecification,
+			OrderingSpecification orderingSpecification) {
+		AST sortSpecification = getASTFactory().create( SORT_SPEC, "{{sort specification}}" );
+		AST sortKey = getASTFactory().create( SORT_KEY, "{{sort key}}" );
+		AST newIdent = getASTFactory().create( ident.getType(), ident.getText() );
+		sortKey.setFirstChild( newIdent );
+		sortSpecification.setFirstChild( sortKey );
+		if ( collationSpecification != null ) {
+			sortSpecification.addChild( collationSpecification );
+		}
+		if ( orderingSpecification != null ) {
+			sortSpecification.addChild( orderingSpecification );
+		}
+		return ( SortSpecification ) sortSpecification;
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentRenderer.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,79 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentRenderer extends GeneratedOrderByFragmentRenderer {
+	private static final Logger log = LoggerFactory.getLogger( OrderByFragmentRenderer.class );
+
+	protected void out(AST ast) {
+		out( ( ( Node ) ast ).getRenderableText() );
+	}
+
+	// handle trace logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	private final ASTPrinter printer = new ASTPrinter( OrderByTemplateTokenTypes.class );
+	private int traceDepth = 0;
+
+	public void traceIn(String ruleName, AST tree) {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = StringHelper.repeat( '-', (traceDepth++ * 2) ) + "-> ";
+		String traceText = ruleName + " (" + buildTraceNodeName(tree) + ")";
+		trace( prefix + traceText );
+	}
+
+	private String buildTraceNodeName(AST tree) {
+		return tree == null
+				? "???"
+				: tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) + "]";
+	}
+
+	public void traceOut(String ruleName, AST tree) {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = "<-" + StringHelper.repeat( '-', (--traceDepth * 2) ) + " ";
+		trace( prefix + ruleName );
+	}
+
+	private void trace(String msg) {
+		log.trace( msg );
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentTranslator.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import java.io.StringReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.hql.ast.util.ASTPrinter;
+
+/**
+ * A translator which coordinates translation of an <tt>order-by</tt> mapping.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentTranslator {
+	private static final Logger log = LoggerFactory.getLogger( OrderByFragmentTranslator.class );
+
+	public final TranslationContext context;
+
+	public OrderByFragmentTranslator(TranslationContext context) {
+		this.context = context;
+	}
+
+	/**
+	 * The main contract, performing the transaction.
+	 *
+	 * @param fragment The <tt>order-by</tt> mapping fragment to be translated.
+	 *
+	 * @return The translated fragment.
+	 */
+	public String render(String fragment) {
+		GeneratedOrderByLexer lexer = new GeneratedOrderByLexer( new StringReader( fragment ) );
+		OrderByFragmentParser parser = new OrderByFragmentParser( lexer, context );
+		try {
+			parser.orderByFragment();
+		}
+		catch ( HibernateException e ) {
+			throw e;
+		}
+		catch ( Throwable t ) {
+			throw new HibernateException( "Unable to parse order-by fragment", t );
+		}
+
+		if ( log.isTraceEnabled() ) {
+			ASTPrinter printer = new ASTPrinter( OrderByTemplateTokenTypes.class );
+			log.trace( printer.showAsString( parser.getAST(), "--- {order-by fragment} ---" ) );
+		}
+
+		GeneratedOrderByFragmentRenderer renderer = new GeneratedOrderByFragmentRenderer();
+		try {
+			renderer.orderByFragment( parser.getAST() );
+		}
+		catch ( HibernateException e ) {
+			throw e;
+		}
+		catch ( Throwable t ) {
+			throw new HibernateException( "Unable to render parsed order-by fragment", t );
+		}
+
+		return renderer.getRenderedFragment();
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderingSpecification.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,72 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models an ordering specification (<tt>ASCENDING</tt> or <tt>DESCENDING</tt>) within a {@link SortSpecification}.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderingSpecification extends Node {
+	public static class Ordering {
+		public static final Ordering ASCENDING = new Ordering( "asc" );
+		public static final Ordering DESCENDING = new Ordering( "desc" );
+
+		private final String name;
+
+		private Ordering(String name) {
+			this.name = name;
+		}
+	}
+
+	private boolean resolved;
+	private Ordering ordering;
+
+	public Ordering getOrdering() {
+		if ( !resolved ) {
+			ordering = resolve( getText() );
+			resolved = true;
+		}
+		return ordering;
+	}
+
+	private static Ordering resolve(String text) {
+		if ( Ordering.ASCENDING.name.equals( text ) ) {
+			return Ordering.ASCENDING;
+		}
+		else if ( Ordering.DESCENDING.name.equals( text ) ) {
+			return Ordering.DESCENDING;
+		}
+		else {
+			throw new IllegalStateException( "Unknown ordering [" + text + "]" );
+		}
+	}
+
+	public String getRenderableText() {
+		return getOrdering().name;
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/SortKey.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,36 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models the container node for the <tt>sort key</tt>, which is the term given by the ANSI SQL specification to the
+ * expression upon which to sort for each {@link SortSpecification}
+ *
+ * @author Steve Ebersole
+ */
+public class SortKey extends Node {
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/SortSpecification.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,82 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models each sorting exprersion.
+ *
+ * @author Steve Ebersole
+ */
+public class SortSpecification extends Node {
+	/**
+	 * Locate the specified {@link SortKey}.
+	 *
+	 * @return The sort key.
+	 */
+	public SortKey getSortKey() {
+		return ( SortKey ) getFirstChild();
+	}
+
+	/**
+	 * Locate the specified <tt>collation specification</tt>, if one.
+	 *
+	 * @return The <tt>collation specification</tt>, or null if none was specified.
+	 */
+	public CollationSpecification getCollation() {
+		AST possible = getSortKey().getNextSibling();
+		return  possible != null && OrderByTemplateTokenTypes.COLLATE == possible.getType()
+				? ( CollationSpecification ) possible
+				: null;
+	}
+
+	/**
+	 * Locate the specified <tt>ordering specification</tt>, if one.
+	 *
+	 * @return The <tt>ordering specification</tt>, or null if none was specified.
+	 */
+	public OrderingSpecification getOrdering() {
+		// IMPL NOTE : the ordering-spec would be either the 2nd or 3rd child (of the overall sort-spec), if it existed,
+		// 		depending on whether a collation-spec was specified.
+
+		AST possible = getSortKey().getNextSibling();
+		if ( possible == null ) {
+			// There was no sort-spec parts specified other then the sort-key so there can be no ordering-spec...
+			return null;
+		}
+
+		if ( OrderByTemplateTokenTypes.COLLATE == possible.getType() ) {
+			// the 2nd child was a collation-spec, so we need to check the 3rd child instead.
+			possible = possible.getNextSibling();
+		}
+
+		return possible != null && OrderByTemplateTokenTypes.ORDER_SPEC == possible.getType()
+				?  ( OrderingSpecification ) possible
+				:  null;
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java (from rev 15683, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/TranslationContext.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,64 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+
+/**
+ * Contract for contextual information required to perform translation.
+*
+* @author Steve Ebersole
+*/
+public interface TranslationContext {
+	/**
+	 * Retrieves the <tt>session factory</tt> for this context.
+	 *
+	 * @return The <tt>session factory</tt>
+	 */
+	public SessionFactoryImplementor getSessionFactory();
+
+	/**
+	 * Retrieves the <tt>dialect</tt> for this context.
+	 *
+	 * @return The <tt>dialect</tt>
+	 */
+	public Dialect getDialect();
+
+	/**
+	 * Retrieves the <tt>SQL function registry/tt> for this context.
+	 *
+	 * @return The SQL function registry.
+	 */
+	public SQLFunctionRegistry getSqlFunctionRegistry();
+
+	/**
+	 * Retrieves the <tt>column mapper</tt> for this context.
+	 *
+	 * @return The <tt>column mapper</tt>
+	 */
+	public ColumnMapper getColumnMapper();
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,103 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+import antlr.Token;
+
+import org.hibernate.sql.ast.common.NodeFactory;
+
+/**
+ * AST factory for the resolve phase of HQL query translation.
+ *
+ * @author Steve Ebersole
+ */
+public class ASTFactoryImpl extends NodeFactory implements HqlNormalizeTokenTypes {
+	private final NormalizationContext resolutionContext;
+
+	public ASTFactoryImpl(NormalizationContext resolutionContext) {
+		this.resolutionContext = resolutionContext;
+	}
+
+	public Class getASTNodeType(int tokenType) {
+		switch ( tokenType ) {
+			case IDENT :
+				return Ident.class;
+			case ENTITY_PERSISTER_REF :
+				return EntityPersisterReference.class;
+			case COLLECTION_PERSISTER_REF :
+				return CollectionPersisterReference.class;
+			case JOIN :
+				return Join.class;
+			case ALIAS_REF :
+				return PersisterAliasReference.class;
+			case PROPERTY_REF :
+				return PropertyReference.class;
+			case INSERT :
+				return InsertStatement.class;
+			case UPDATE :
+				return UpdateStatement.class;
+			case DELETE :
+				return DeleteStatement.class;
+			case QUERY :
+				return SelectStatement.class;
+			case QUERY_SPEC :
+				return QuerySpec.class;
+			case SELECT_ITEM :
+				return SelectItem.class;
+			default:
+				return determineDefaultNodeClass();
+		}
+	}
+
+	protected AST createUsingCtor(Token token, String className) {
+		return super.createUsingCtor( token, className );
+	}
+
+	/**
+	 * Instantiate the AST node of the given type.
+	 *
+	 * @param c The AST class to instantiate.
+	 * @return The instantiated and initialized node.
+	 */
+	protected AST create(Class c) {
+		AST ast = super.create(  c );
+		if ( ast != null ) {
+			initialize( ast );
+		}
+		return ast;
+	}
+
+	/**
+	 * Perform any optional requested initializatio on the node.  In this impl, that means to look at the node's
+	 * interfaces.
+	 *
+	 * @param ast The node
+	 */
+	protected void initialize(AST ast) {
+		if ( ast instanceof NormalizationContextAwareNode ) {
+			( ( NormalizationContextAwareNode ) ast ).injectResolutionContext( resolutionContext );
+		}
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Base class for {@link PersisterReference} implementations.  Mainly it centralizes handling
+ * of reusable proerty joins.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPersisterReference extends Node implements PersisterReference {
+	private Map reusablePropertyJoins = new HashMap();
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Join locateReusablePropertyJoin(String path) {
+		return ( Join ) reusablePropertyJoins.get( path );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void registerReusablePropertyJoin(String path, Join join) {
+		reusablePropertyJoins.put( path, join );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public PersisterReference locatePersisterReference() {
+		return this;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * Handles generating synthetic or implicit aliases.
+ *
+ * @author Steve Ebersole
+ */
+public class AliasBuilder {
+	private int unaliasedCount = 0;
+
+	/**
+	 * Builds a unique implicit alias.
+	 *
+	 * @return The generated alias.
+	 */
+	public synchronized String buildUniqueImplicitAlias() {
+		return "<gen:" + unaliasedCount++ + ">";
+	}
+
+	/**
+	 * Determine if the given alias is implicit.
+	 *
+	 * @param alias The alias to check
+	 * @return True/false.
+	 */
+	public static boolean isImplicitAlias(String alias) {
+		return alias == null || ( alias.startsWith( "<gen:" ) && alias.endsWith( ">" ) );
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,146 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.AssertionFailure;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.ComponentType;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.collection.CollectionPropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+
+/**
+ * Represents a reference to an {@link org.hibernate.persister.collection.CollectionPersister}
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionPersisterReference extends AbstractPersisterReference
+		implements NormalizationContextAwareNode, DisplayableNode {
+	private NormalizationContext resolutionContext;
+	private transient QueryableCollection persister;
+	private transient CollectionPropertyMapping propertyMapping;
+
+	/**
+	 * Retrieve the collection "role" identifying the underlying {@link org.hibernate.persister.collection.CollectionPersister}
+	 *
+	 * @return The collection role
+	 */
+	public String getRole() {
+		return getFirstChild().getText();
+	}
+
+	public String getAlias() {
+		return getFirstChild().getNextSibling().getText();
+	}
+
+	public String getName() {
+		return getRole();
+	}
+
+	public boolean isCollection() {
+		return true;
+	}
+
+	/**
+	 * Retrieve a reference to the underlying collection persister.
+	 *
+	 * @return The collection persister.
+	 */
+	public QueryableCollection getCollectionPersister() {
+		if ( persister == null ) {
+			persister = ( QueryableCollection ) getSessionFactory().getCollectionPersister( getRole() );
+		}
+		return persister;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public AssociationType getPersisterType() {
+		return ( AssociationType ) getCollectionPersister().getElementType();
+	}
+
+	public Type getPropertyType(String propertyName) {
+		// this should not be called for "collection properties" (i.e., SIZE, MAXELEMENT, etc)...
+		Type elementType = getCollectionPersister().getElementType();
+		if ( elementType.isAssociationType() ) {
+			// a collection of entities
+			EntityType elementEntityType = ( EntityType ) elementType;
+			try {
+				Queryable elementEntityPersister = ( Queryable ) elementEntityType
+						.getAssociatedJoinable( getSessionFactory() );
+				return elementEntityPersister.getPropertyType( propertyName );
+			}
+			catch( Throwable ignore ) {
+				// ignore
+			}
+		}
+		else if ( elementType.isComponentType() ) {
+			ComponentType elementComponentType = ( ComponentType ) elementType;
+			String[] subPropertyNames = elementComponentType.getPropertyNames();
+			for ( int i = 0; i < subPropertyNames.length; i++ ) {
+				if ( subPropertyNames[i].equals( propertyName ) ) {
+					return elementComponentType.getSubtypes()[i];
+				}
+			}
+		}
+		return null;
+	}
+
+	public boolean containsProperty(String propertyName) {
+		return getPropertyType( propertyName ) != null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void injectResolutionContext(NormalizationContext resolutionContext) {
+		this.resolutionContext = resolutionContext;
+	}
+
+	private final SessionFactoryImplementor getSessionFactory() {
+		if ( resolutionContext == null ) {
+			throw new AssertionFailure( "resolution context was null on attempt to retrieve session factory reference" );
+		}
+		return resolutionContext.getSessionFactoryImplementor();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String toString() {
+		return "CollectionPersisterReference [role=" + getRole()
+				+ ",alias=" + getAlias()
+				+ ",element-type=" + getCollectionPersister().getElementType().getName()
+				+ "]";
+	}
+
+	public String getDisplayText() {
+		return getRole() + " (" + getAlias() + ")";
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import org.hibernate.HibernateException;
+
+/**
+ * Specialized statement node for representing <tt>DELETE</tt> statements
+ *
+ * @author Steve Ebersole
+ */
+public class DeleteStatement extends Node implements Statement {
+	public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext normalizationContext) {
+		return new BasicPathNormalizationStrategySupport( normalizationContext ) {
+			protected void validateJoinCreation(PersisterReference origin, String property) {
+				throw new HibernateException(
+						"delete statement cannot contain implicit join path expressions"
+				);
+			}
+		};
+	}
+}
\ No newline at end of file

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Indicates that a query attempted to define the same alias more than once.
+ *
+ * @author Steve Ebersole
+ */
+public class DuplicateAliasException extends HibernateException {
+	private final String alias;
+
+	public DuplicateAliasException(String alias) {
+		super( "Attempt to register alias [" + alias + "] multiple times" );
+		this.alias = alias;
+	}
+
+	public String getAlias() {
+		return alias;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,151 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.Iterator;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.sql.ast.util.ASTChildIterator;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.AssertionFailure;
+import org.hibernate.util.EmptyIterator;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.persister.entity.Queryable;
+
+/**
+ * Represents a reference to an {@link org.hibernate.persister.entity.EntityPersister}
+ *
+ * @author Steve Ebersole
+ */
+public class EntityPersisterReference extends AbstractPersisterReference
+		implements NormalizationContextAwareNode, DisplayableNode {
+	private NormalizationContext resolutionContext;
+	private transient Queryable persister;
+
+	/**
+	 * Retrieve the entity name of the underlying {@link org.hibernate.persister.entity.EntityPersister}
+	 *
+	 * @return The entity name
+	 */
+	public String getEntityName() {
+		return getFirstChild().getText();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getAlias() {
+		return getFirstChild().getNextSibling().getText();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getName() {
+		return getEntityName();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isCollection() {
+		return false;
+	}
+
+	/**
+	 * Retrieves a reference to the underlying entity persister.
+	 *
+	 * @return The underlying entity persister.
+	 */
+	public Queryable getEntityPersister() {
+		if ( persister == null ) {
+			persister = ( Queryable ) getSessionFactory().getEntityPersister( getEntityName() );
+		}
+		return persister;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public AssociationType getPersisterType() {
+		return ( AssociationType ) getEntityPersister().getType();
+	}
+
+	public Type getPropertyType(String propertyName) {
+		try {
+			return getEntityPersister().getPropertyType( propertyName );
+		}
+		catch( Throwable ignore ) {
+			return null;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean containsProperty(String propertyName) {
+		return getPropertyType( propertyName ) != null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void injectResolutionContext(NormalizationContext resolutionContext) {
+		this.resolutionContext = resolutionContext;
+	}
+
+	private SessionFactoryImplementor getSessionFactory() {
+		if ( resolutionContext == null ) {
+			throw new AssertionFailure( "resolution context was null on attempt to retrieve session factory reference" );
+		}
+		return resolutionContext.getSessionFactoryImplementor();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String toString() {
+		return "EntityPersisterReference [entity-name=" + getEntityName() + ",alias=" + getAlias() + "]";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getDisplayText() {
+		return getEntityName() + " (" + getAlias() + ")";
+	}
+
+	public Iterator locateJoins() {
+		AST firstJoin = getFirstChild().getNextSibling().getNextSibling();
+		if ( firstJoin == null ) {
+			return EmptyIterator.INSTANCE;
+		}
+		else {
+			return new ASTChildIterator( firstJoin );
+		}
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,98 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * Defines a hierarchical representation of a persister reference context.
+ * <p/>
+ * Generally speaking this notion should really only hold for SELECT statements.  Does not make sense for
+ * INSERT or UPDATE or DELETE statements to have a parent, as that would mean they are being used as in a subqquery
+ * (certainly, however, it makes sense for these to *be the parent* context...).
+ *
+ * @author Steve Ebersole
+ */
+public class HierarchicalPersisterReferenceContext extends RootPersisterReferenceContext implements PersisterReferenceContext {
+	private final PersisterReferenceContext parent;
+
+	public HierarchicalPersisterReferenceContext(PersisterReferenceContext parent) {
+		super();
+		if ( parent == null ) {
+			throw new IllegalArgumentException( "Parent PersisterReferenceContext cannot be null!" );
+		}
+		this.parent = parent;
+	}
+
+	/**
+	 * Get the parent context of this context.
+	 *
+	 * @return Our parent context.
+	 */
+	public PersisterReferenceContext getParent() {
+		return parent;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p/>
+	 * Overriden to project the lookup to our parent if not found locally.
+	 */
+	public boolean isContainedAlias(String alias) {
+		return super.isContainedAlias( alias ) || getParent().isContainedAlias( alias );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p/>
+	 * Overriden to project the lookup to our parent if not found locally.
+	 */
+	public boolean isContainedExposedProperty(String propertyName) {
+		return super.isContainedExposedProperty( propertyName ) || getParent().isContainedExposedProperty( propertyName );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p/>
+	 * Overriden to project the lookup to our parent if not found locally.
+	 */
+	public PersisterReference locatePersisterReferenceByAlias(String alias) {
+		PersisterReference persisterReference = super.locatePersisterReferenceByAlias( alias );
+		if ( persisterReference == null ) {
+			persisterReference = getParent().locatePersisterReferenceByAlias( alias );
+		}
+		return persisterReference;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * <p/>
+	 * Overriden to project the lookup to our parent if not found locally.
+	 */
+	public PersisterReference locatePersisterReferenceExposingProperty(String propertyName) {
+		PersisterReference persisterReference = super.locatePersisterReferenceExposingProperty( propertyName );
+		if ( persisterReference == null ) {
+			persisterReference = getParent().locatePersisterReferenceExposingProperty( propertyName );
+		}
+		return persisterReference;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,374 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.util.ParseErrorHandler;
+import org.hibernate.sql.ast.util.ErrorCounter;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.FromClausePathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.SelectClausePathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.OnFragmentPathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.WithFragmentPathNormalizationStrategy;
+import org.hibernate.QueryException;
+import org.hibernate.MappingException;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategyStack;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.util.StringHelper;
+
+import antlr.RecognitionException;
+import antlr.ASTFactory;
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class HqlNormalizer extends GeneratedHqlNormalizer implements NormalizationContext {
+	private static final Logger log = LoggerFactory.getLogger( HqlNormalizer.class );
+
+	private final SessionFactoryImplementor sessionFactory;
+	private final PersisterReferenceBuilder persisterReferenceBuilder;
+	private final ParseErrorHandler parseErrorHandler = new ErrorCounter();
+	private final ASTPrinter printer = new ASTPrinter( HqlNormalizeTokenTypes.class );
+	private final AliasBuilder aliasBuilder = new AliasBuilder();
+	private final PathNormalizationStrategyStack pathNormalizationStrategyStack = new PathNormalizationStrategyStack();
+
+	private int traceDepth = 0;
+
+	public HqlNormalizer(SessionFactoryImplementor sessionFactory) {
+		super();
+		this.sessionFactory = sessionFactory;
+		this.persisterReferenceBuilder = new PersisterReferenceBuilder( this );
+		super.setASTFactory( new ASTFactoryImpl( this ) );
+	}
+
+	public ASTPrinter getPrinter() {
+		return printer;
+	}
+
+
+	// overrides of Antlr infastructure methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void reportError(RecognitionException e) {
+		getParseErrorHandler().reportError( e );
+	}
+
+	public void reportError(String s) {
+		getParseErrorHandler().reportError( s );
+	}
+
+	public void reportWarning(String s) {
+		getParseErrorHandler().reportWarning( s );
+	}
+
+	public ParseErrorHandler getParseErrorHandler() {
+		return parseErrorHandler;
+	}
+
+	static public void panic() {
+		//overriden to avoid System.exit
+		throw new QueryException( "Parser: panic" );
+	}
+
+	public void setASTFactory(ASTFactory astFactory) {
+		throw new UnsupportedOperationException( "not allowed!" );
+	}
+
+
+	// Resolution state ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	private PersisterReferenceContext currentPersisterReferenceContext;
+
+	public PersisterReferenceContext getCurrentPersisterReferenceContext() {
+		return currentPersisterReferenceContext;
+	}
+
+	protected void pushStatement(AST statementNode) {
+		if ( currentPersisterReferenceContext == null ) {
+			currentPersisterReferenceContext = new RootPersisterReferenceContext();
+		}
+		else {
+			currentPersisterReferenceContext = new HierarchicalPersisterReferenceContext( currentPersisterReferenceContext );
+		}
+
+		pathNormalizationStrategyStack.push( new BasicPathNormalizationStrategySupport( this ) );
+	}
+
+	protected void popStatement() {
+		pathNormalizationStrategyStack.pop();
+		if ( currentPersisterReferenceContext instanceof HierarchicalPersisterReferenceContext ) {
+			currentPersisterReferenceContext = ( ( HierarchicalPersisterReferenceContext ) currentPersisterReferenceContext ).getParent();
+		}
+		else {
+			currentPersisterReferenceContext = null;
+		}
+	}
+
+
+	// ResolutionContext impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public AliasBuilder getAliasBuilder() {
+		return aliasBuilder;
+	}
+
+	protected String buildUniqueImplicitAlias() {
+		return aliasBuilder.buildUniqueImplicitAlias();
+	}
+
+	public SessionFactoryImplementor getSessionFactoryImplementor() {
+		return sessionFactory;
+	}
+
+	public PersisterReferenceBuilder getPersisterReferenceBuilder() {
+		return persisterReferenceBuilder;
+	}
+
+
+	// handle trace logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void traceIn(String ruleName, AST tree) {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = StringHelper.repeat( '-', (traceDepth++ * 2) ) + "-> ";
+		String traceText = ruleName + " (" + buildTraceNodeName(tree) + ")";
+		trace( prefix + traceText );
+	}
+
+	private String buildTraceNodeName(AST tree) {
+		return tree == null
+				? "???"
+				: tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) + "]";
+	}
+
+	public void traceOut(String ruleName, AST tree) {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = "<-" + StringHelper.repeat( '-', (--traceDepth * 2) ) + " ";
+		trace( prefix + ruleName );
+	}
+
+	private void trace(String msg) {
+		System.out.println( msg );
+//		log.trace( msg );
+	}
+
+
+	// AST output methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void dumpAst(AST ast) {
+		dumpAst( ast, "DUMP" );
+	}
+
+	public void dumpAst(AST ast, String header) {
+		log.info( printer.showAsString( ast, header ) );
+	}
+
+	public void showAst(AST ast, PrintStream out) {
+		showAst( ast, new PrintWriter( out ) );
+	}
+
+	private void showAst(AST ast, PrintWriter pw) {
+		printer.showAst( ast, pw );
+	}
+
+
+	private String textOrNull(AST ast) {
+		return ast == null ? null : ast.getText();
+	}
+
+
+	// function processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	private boolean processingFunction;
+
+	protected void startingFunction() {
+		processingFunction = true;
+	}
+
+	protected void endingFunction() {
+		processingFunction = false;
+	}
+
+	public boolean isCurrentlyProcessingFunction() {
+		return processingFunction;
+	}
+
+
+	// persister-related semntic action overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected AST normalizeEntityName(AST node) throws SemanticException {
+		String entityName = node.getText();
+		if ( !isEntityName( entityName ) ) {
+			final String importedName = getSessionFactoryImplementor().getImportedClassName( entityName );
+			if ( !isEntityName( importedName ) ) {
+				throw new NoSuchEntityNameException( node );
+			}
+			node.setText( importedName );
+		}
+		return node;
+	}
+
+	private boolean isEntityName(String name) {
+		try {
+			return getSessionFactoryImplementor().getEntityPersister( name ) != null;
+		}
+		catch ( MappingException me ) {
+			return false;
+		}
+	}
+
+	protected void registerPersisterReference(AST reference) {
+		getCurrentPersisterReferenceContext().registerPersisterReference( ( PersisterReference ) reference );
+	}
+
+	protected boolean isPersisterReferenceAlias(AST alias) {
+		log.trace( "Checking [" + textOrNull( alias ) + "] as persister-ref alias" );
+		return getCurrentPersisterReferenceContext().isContainedAlias( alias.getText() );
+	}
+
+	protected boolean isCollectionPersisterReferenceAlias(AST alias) {
+		return getCurrentPersisterReferenceContext().locatePersisterReferenceByAlias( alias.getText() ).isCollection();
+	}
+
+
+	// property-related semntic action overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    protected String locateOwningPersisterAlias(AST property) {
+		PersisterReference persisterReference = getCurrentPersisterReferenceContext()
+				.locatePersisterReferenceExposingProperty( property.getText() );
+		return persisterReference == null ? null : persisterReference.getAlias();
+	}
+
+
+	// path normalization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected AST normalizeQualifiedRoot(AST alias) {
+		log.debug( "normalizing path expression root as alias [" + alias.getText() + "]" );
+		return pathNormalizationStrategyStack.getCurrent().handleRoot( getCurrentPersisterReferenceContext().locatePersisterReferenceByAlias( alias.getText() ) );
+    }
+
+    protected AST normalizeUnqualifiedRoot(AST propertyName) {
+		log.debug( "normalizing path expression root as unqualified property [" + propertyName.getText() + "]" );
+		PathedPropertyReferenceSource root = pathNormalizationStrategyStack.getCurrent().handleRoot( getCurrentPersisterReferenceContext().locatePersisterReferenceExposingProperty( propertyName.getText() ) );
+		return root.handleIntermediatePathPart( ( Ident ) propertyName );
+	}
+
+	protected AST normalizePropertyPathIntermediary(AST source, AST propertyNameNode) {
+		log.trace( "normalizing intermediate path expression [" + textOrNull( propertyNameNode ) + "]" );
+		return pathNormalizationStrategyStack.getCurrent().handleIntermediatePathPart( ( PathedPropertyReferenceSource ) source, ( Ident ) propertyNameNode );
+    }
+
+    protected AST normalizePropertyPathTerminus(AST source, AST propertyNameNode) {
+		log.trace( "normalizing terminal path expression [" + textOrNull( propertyNameNode ) + "]" );
+		return pathNormalizationStrategyStack.getCurrent().handleTerminalPathPart( ( PathedPropertyReferenceSource ) source, ( Ident ) propertyNameNode );
+    }
+
+
+	// property path normalization strategies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected void pushFromClausePropertyPathContext(AST joinTypeNode, AST fetch, AST alias, AST propertyFetch) {
+		pathNormalizationStrategyStack.push(
+				new FromClausePathNormalizationStrategy(
+						this,
+						resolveJoinType( joinTypeNode ),
+						fetch != null,
+						propertyFetch != null,
+						textOrNull( alias )
+				)
+		);
+	}
+
+	private JoinType resolveJoinType(AST joinType) {
+		int joinTypeType = joinType == null ? INNER : joinType.getType();
+		switch ( joinTypeType ) {
+			case INNER:
+				return JoinType.INNER;
+			case LEFT:
+				return JoinType.LEFT;
+			case RIGHT:
+				return JoinType.RIGHT;
+			case FULL:
+				return JoinType.FULL;
+		}
+		// if no match found, throw exception
+		throw new QueryException( "Unrecognized join type [" + joinType.getText() + "]" );
+	}
+
+	protected void popFromClausePropertyPathContext() {
+		popPathNormalizationContext();
+	}
+
+	private void popPathNormalizationContext() {
+		pathNormalizationStrategyStack.pop();
+	}
+
+	protected void pushSelectClausePropertyPathContext() {
+		pathNormalizationStrategyStack.push( new SelectClausePathNormalizationStrategy( this ) );
+	}
+
+	protected void popSelectClausePropertyPathContext() {
+		popPathNormalizationContext();
+	}
+
+	protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+		pathNormalizationStrategyStack.push( 
+				new OnFragmentPathNormalizationStrategy( this, ( PersisterReference ) rhsPersisterReference )
+		);
+	}
+
+	protected void popOnFragmentPropertyPathContext() {
+		popPathNormalizationContext();
+	}
+
+	protected void pushWithFragmentPropertyPathContext(AST rhsPropertyReference) {
+		PropertyReference propertyReference = ( PropertyReference ) rhsPropertyReference;
+		PersisterReference lhs = propertyReference.getSource().locatePersisterReference();
+//		PersisterReference rhs = null;
+//		pathNormalizationStrategyStack.push(
+//				new WithFragmentPathNormalizationStrategy( this, lhs, rhs )
+//		);
+		pathNormalizationStrategyStack.push( new WithFragmentPathNormalizationStrategy( this, lhs ) );
+	}
+
+	protected void popWithFragmentPropertyPathContext() {
+		super.popWithFragmentPropertyPathContext();
+	}
+
+	protected void applyWithFragment(AST withFragment) {
+		( ( WithFragmentPathNormalizationStrategy ) pathNormalizationStrategyStack.getCurrent() ).applyWithFragment( withFragment );
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Represents an {@link HqlNormalizeTokenTypes#IDENT} node.  Defined as a separate Node class mostly to allow for
+ * typesafety in argument passing.
+ *
+ * @author Steve Ebersole
+ */
+public class Ident extends Node {
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import org.hibernate.HibernateException;
+
+/**
+ * Specialized statement node for representing <tt>INSERT</tt> statements
+ *
+ * @author Steve Ebersole
+ */
+public class InsertStatement extends Node implements Statement {
+	public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext normalizationContext) {
+		return new BasicPathNormalizationStrategySupport( normalizationContext ) {
+			protected void validateJoinCreation(PersisterReference origin, String property) {
+				throw new HibernateException(
+						"insert statement cannot contain implicit join path expressions"
+				);
+			}
+		};
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,58 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.JoinType;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Join extends Node {
+	private boolean forced = false;
+
+	public void force() {
+		forced = true;
+	}
+
+	public boolean isForced() {
+		return forced;
+	}
+
+	public Node getJoinType() {
+		return ( Node ) getFirstChild();
+	}
+
+	public JoinType getEnumeratedJoinType() {
+		return JoinType.resolve( getJoinType() );
+	}
+
+	public PersisterReference getRhs() {
+		return ( PersisterReference ) getFirstChild().getNextSibling();
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.DetailedSemanticException;
+
+/**
+ * Thrown to indicate that a specified entity name could not be resolved.
+ *
+ * @author Steve Ebersole
+ */
+public class NoSuchEntityNameException extends DetailedSemanticException {
+	private final String entityName;
+
+	public NoSuchEntityNameException(AST entityNameNode) {
+		super( "Unable to resolve entity name [" + entityNameNode.getText() + "]", entityNameNode );
+		this.entityName = entityNameNode.getText();
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.ASTFactory;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.sql.ast.util.ASTPrinter;
+
+/**
+ * Defines the environment or context in which normalization is occuring, more specifically
+ * defining the capabilities available in said context.
+*
+* @author Steve Ebersole
+*/
+public interface NormalizationContext {
+	/**
+	 * The factory for creating AST nodes in this context.
+	 *
+	 * @return The AST node factory.
+	 */
+	public ASTFactory getASTFactory();
+
+	/**
+	 * The session factory available for this context.  Providing, for example, mapping information.
+	 *
+	 * @return The session factory.
+	 */
+	public SessionFactoryImplementor getSessionFactoryImplementor();
+
+	/**
+	 * The alias builder available in this context.
+	 *
+	 * @return The alias builder.
+	 */
+	public AliasBuilder getAliasBuilder();
+
+	/**
+	 * The current {@link PersisterReferenceContext} for this context.  The {@link PersisterReferenceContext}
+	 * can change in relation to subqueries and such.  See {@link PersisterReferenceContext} docs for more info.
+	 *
+	 * @return The current {@link PersisterReferenceContext} for this normalization context.
+	 */
+	public PersisterReferenceContext getCurrentPersisterReferenceContext();
+
+	/**
+	 * The builder of {@link PersisterReference} instances for this context.
+	 *
+	 * @return The {@link PersisterReference} builder.
+	 */
+	public PersisterReferenceBuilder getPersisterReferenceBuilder();
+
+	/**
+	 * The AST printer available for this context.
+	 *
+	 * @return The AST printer.
+	 */
+	public ASTPrinter getPrinter();
+
+	/**
+	 * Is this context currently processing a function?
+	 *
+	 * @return True or false.
+	 */
+	public boolean isCurrentlyProcessingFunction();
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * Injection contract for {@link org.hibernate.sql.ast.common.Node nodes} needing access to the
+ * {@link NormalizationContext}.
+ *
+ * @author Steve Ebersole
+ */
+public interface NormalizationContextAwareNode {
+	/**
+	 * {@link NormalizationContext} injection service.
+	 *
+	 * @param resolutionContext The resolution context.
+	 */
+	public void injectResolutionContext(NormalizationContext resolutionContext);
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.type.Type;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterAliasReference extends Node implements PropertyReferenceSource, NormalizationContextAwareNode {
+	private NormalizationContext resolutionContext;
+
+	public String getPersisterAlias() {
+		return getText();
+	}
+
+	public PersisterReference locatePersisterReference() {
+		return resolutionContext.getCurrentPersisterReferenceContext()
+				.locatePersisterReferenceByAlias( getPersisterAlias() );
+	}
+
+	public void injectResolutionContext(NormalizationContext resolutionContext) {
+		this.resolutionContext = resolutionContext;
+	}
+
+	public Type getPropertyType(String property) {
+		return locatePersisterReference().getPropertyType( property );
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,96 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+
+/**
+ * Contract for persister references.
+ *
+ * @author Steve Ebersole
+ */
+public interface PersisterReference extends AST, PropertyReferenceSource {
+	/**
+	 * Get the alias assigned to this persister reference.  May be explcitly defined by the query author or
+	 * supplied by {@link AliasBuilder#buildUniqueImplicitAlias()}, but all persister references will have an alias.
+	 *
+	 * @return This persister reference's alias.
+	 */
+	public String getAlias();
+
+	/**
+	 * Get the name of this persister reference.
+	 * @return The name.
+	 */
+	public String getName();
+
+	/**
+	 * Is this persister reference representing a collection persister?
+	 *
+	 * @return True/false.
+	 */
+	public boolean isCollection();
+
+	/**
+	 * Get the type mapping of the underlying persister,
+	 *
+ 	 * @return The unerlygin persister's type mapping.
+	 */
+	public AssociationType getPersisterType();
+
+	/**
+	 * Get the type mapping of a property originating from this persister reference.
+	 *
+	 * @param propertyName The property name.
+	 * @return The type mapping.
+	 */
+	public Type getPropertyType(String propertyName);
+
+	/**
+	 * Does this persister reference represent a persister which contains a property of the given name?
+	 *
+	 * @param propertyName The property name.
+	 * @return True/false.
+	 */
+	public boolean containsProperty(String propertyName);
+
+	/**
+	 * Locate a reusable property join originating from this persister reference.
+	 *
+	 * @param path The property path.
+	 * @return The reusable join, or null if none yet {@link #registerReusablePropertyJoin registered}.
+	 */
+	public Join locateReusablePropertyJoin(String path);
+
+	/**
+	 * Register a reusable property join.
+	 *
+	 * @param path The property path
+	 * @param join The join to be registered.
+	 */
+	public void registerReusablePropertyJoin(String path, Join join);
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,162 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import antlr.collections.AST;
+import antlr.ASTFactory;
+
+/**
+ * Centralization of code needed to build a {@link PersisterReference}
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterReferenceBuilder implements HqlNormalizeTokenTypes {
+	public static final Log log = LogFactory.getLog( PersisterReferenceBuilder.class );
+
+	private final NormalizationContext normalizationContext;
+
+	public PersisterReferenceBuilder(NormalizationContext normalizationContext) {
+		this.normalizationContext = normalizationContext;
+	}
+
+	private ASTFactory astFactory() {
+		return normalizationContext.getASTFactory();
+	}
+
+	private PersisterReferenceContext persisterReferenceContext() {
+		return normalizationContext.getCurrentPersisterReferenceContext();
+	}
+
+	private AliasBuilder aliasBuilder() {
+		return normalizationContext.getAliasBuilder();
+	}
+
+	private SessionFactoryImplementor sessionFactory() {
+		return normalizationContext.getSessionFactoryImplementor();
+	}
+
+	// exposed services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Builds an entity persister reference
+	 *
+	 * @param entityName The entity name to which to build a PersisterReference.
+	 * @param alias The alias (or null) to apply to the built PersisterReference.
+	 * @param propertyFetching Whether lazy property fetching should be enabled.
+	 * @return The built PersisterReference
+	 */
+	public EntityPersisterReference buildEntityPersisterReference(
+			String entityName,
+			String alias,
+			boolean propertyFetching) {
+		EntityPersister persister = lookupEntityPersister( entityName );
+		String aliasText = determineAlias( alias );
+
+		AST entityNameNode = astFactory().create( ENTITY_NAME, persister.getEntityName() );
+		AST aliasNode = astFactory().create( ALIAS, aliasText );
+		AST persisterReference = astFactory().create( ENTITY_PERSISTER_REF );
+		persisterReference.setFirstChild( entityNameNode );
+		persisterReference.addChild( aliasNode );
+		if ( propertyFetching ) {
+			persisterReference.addChild( astFactory().create( PROP_FETCH ) );
+		}
+
+		EntityPersisterReference entityPersisterReference = ( EntityPersisterReference ) persisterReference;
+		persisterReferenceContext().registerPersisterReference( entityPersisterReference );
+		return entityPersisterReference;
+	}
+
+	/**
+	 * Builds a collection persister reference
+	 *
+	 * @param collectionRole The {@link org.hibernate.persister.collection.CollectionPersister#getRole() collection role}
+	 * for which to build a PersisterReference.
+	 * @param alias The alias (or null) to apply to the built PersisterReference.
+	 * @param propertyFetching Whether lazy property fetching should be enabled.
+	 * @return The built PersisterReference
+	 */
+	public CollectionPersisterReference buildCollectionPersisterReference(
+			String collectionRole, 
+			String alias,
+			boolean propertyFetching) {
+		// todo : is this the structure we want here?
+		String aliasText = determineAlias( alias );
+
+		AST collectionRoleNode = astFactory().create( COLLECTION_ROLE, collectionRole );
+		AST aliasNode = astFactory().create( ALIAS, aliasText );
+		AST persisterReference = astFactory().create( COLLECTION_PERSISTER_REF );
+		persisterReference.setFirstChild( collectionRoleNode );
+		persisterReference.addChild( aliasNode );
+		if ( propertyFetching ) {
+			persisterReference.addChild( astFactory().create( PROP_FETCH ) );
+		}
+
+
+		CollectionPersisterReference collectionPersisterReference = ( CollectionPersisterReference ) persisterReference;
+		persisterReferenceContext().registerPersisterReference( collectionPersisterReference );
+		return collectionPersisterReference;
+	}
+
+	private EntityPersister lookupEntityPersister(String name) {
+		// NOTE : the parser should have already normalized the entity name...
+		try {
+			// First, try to get the persister using the class name directly.
+			return sessionFactory().getEntityPersister( name );
+		}
+		catch ( MappingException ignore ) {
+			// unable to locate it using this name
+		}
+
+		// If that didn't work, try using the 'import' name.
+		String importedClassName = sessionFactory().getImportedClassName( name );
+		if ( importedClassName == null ) {
+			return null;
+		}
+		return sessionFactory().getEntityPersister( importedClassName );
+	}
+
+	private String determineAlias(String alias) {
+		if ( alias == null ) {
+			return aliasBuilder().buildUniqueImplicitAlias();
+		}
+		else {
+			if ( persisterReferenceContext().isContainedAlias( alias ) ) {
+				throw new DuplicateAliasException( alias );
+			}
+			return alias;
+		}
+	}
+
+	public static boolean isImplicitAlias(String alias) {
+		return AliasBuilder.isImplicitAlias( alias );
+	}
+
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,81 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface PersisterReferenceContext {
+	/**
+	 * Does the given text represent an alias for a persister within this context?
+	 *
+	 * @param text The potential persister alias.
+	 * @return True if given text is a persister alias; false otherwise.
+	 */
+	public boolean isContainedAlias(String text);
+
+	/**
+	 * Does the given text represent a property exposed from a persister in this context?
+	 *
+	 * @param propertyName The potential property name.
+	 * @return True if a persister in this context exposes such a property; false otherwise.
+	 */
+	public boolean isContainedExposedProperty(String propertyName);
+
+	/**
+	 * ???
+	 * todo : needed?
+	 *
+	 * @param aliasOrPropertyName
+	 * @return
+	 */
+	public PersisterReference locatePersisterReference(String aliasOrPropertyName);
+
+	/**
+	 * Locate a {@link PersisterReference} by alias.
+	 *
+	 * @param alias The alias by which to locate the persister reference.
+	 * @return The persister reference, or null.
+	 */
+	public PersisterReference locatePersisterReferenceByAlias(String alias);
+
+	/**
+	 * Locate an persister reference in this context which exposes the
+	 * specified property.
+	 *
+	 * @param propertyName The name of the property.
+	 * @return The persister reference, or null.
+	 */
+	public PersisterReference locatePersisterReferenceExposingProperty(String propertyName);
+
+	/**
+	 * Registers a persister reference in this context.
+	 *
+	 * @param persisterReference The persister reference to register.
+	 */
+	public void registerPersisterReference(PersisterReference persisterReference);
+
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,66 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.type.Type;
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class PropertyReference extends Node {
+	private String originalPath;
+
+	public String getOriginalPath() {
+		return originalPath;
+	}
+
+	public void injectOriginalPath(String originalPath) {
+		if ( originalPath == null ) {
+			this.originalPath = originalPath;
+		}
+	}
+
+	public PropertyReferenceSource getSource() {
+		return ( PropertyReferenceSource ) getFirstChild();
+	}
+
+	public Node getPropertyNameNode() {
+		return ( Node ) getFirstChild().getNextSibling();
+	}
+
+	public String getPropertyName() {
+		return getPropertyNameNode().getText();
+	}
+
+	public Type getMappingType() {
+		return getSource().getPropertyType( getPropertyName() );
+	}
+
+	public String getNormalizedPath() {
+		return getFirstChild().getText() + '.' + getPropertyName();
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.type.Type;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface PropertyReferenceSource extends AST {
+	public PersisterReference locatePersisterReference();
+	public Type getPropertyType(String property);
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class QuerySpec extends Node {
+	public Node locateFromClause() {
+		return ( Node ) getFirstChild().getFirstChild();
+	}
+
+	public Node locateSelectClause() {
+		return ( Node ) locateFromClause().getNextSibling();
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,116 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.QueryException;
+
+/**
+ * Defines the contract for implementors of a "context" or a "scope" for references to persisters.  Generally speaking,
+ * this maps to the notion of a FROM clause in a SELECT statement.  However, DML operations also have a notion of a
+ * persister reference.  This, then, acts as the abstraction of these grouped references to persisters.
+ *
+ * @see PersisterReference
+ *
+ * @author Steve Ebersole
+ */
+public class RootPersisterReferenceContext implements PersisterReferenceContext {
+	private static final Logger log = LoggerFactory.getLogger( RootPersisterReferenceContext.class );
+
+	private List persisterReferences = new ArrayList();
+	private Map aliasXref = new HashMap();
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void registerPersisterReference(PersisterReference persisterReference) {
+		if ( persisterReference.getAlias() == null ) {
+			throw new IllegalArgumentException( "unexpected null persister-reference alias" );
+		}
+		persisterReferences.add( persisterReference );
+		aliasXref.put( persisterReference.getAlias(), persisterReference );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isContainedAlias(String alias) {
+		return aliasXref.containsKey( alias );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isContainedExposedProperty(String propertyName) {
+		// a matching alias always takes precedence...
+		return ( ! isContainedAlias( propertyName ) ) && locatePersisterReferenceExposingProperty( propertyName ) != null;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public PersisterReference locatePersisterReference(String aliasOrPropertyName) {
+		PersisterReference persisterReference = locatePersisterReferenceByAlias( aliasOrPropertyName );
+		if ( persisterReference == null ) {
+			persisterReference = locatePersisterReferenceExposingProperty( aliasOrPropertyName );
+		}
+		return persisterReference;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public PersisterReference locatePersisterReferenceByAlias(String alias) {
+		log.trace( "attempting to resolve [" + alias + "] as persister reference alias" );
+		return ( PersisterReference ) aliasXref.get( alias );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public PersisterReference locatePersisterReferenceExposingProperty(String propertyName) {
+		log.trace( "attempting to resolve [" + propertyName + "] as unqualified property" );
+		PersisterReference persisterReference = null;
+		Iterator itr = persisterReferences.iterator();
+		while( itr.hasNext() ) {
+			final PersisterReference test = ( PersisterReference ) itr.next();
+			if ( test.containsProperty( propertyName ) ) {
+				if ( persisterReference != null ) {
+					// todo : better exception type
+					throw new QueryException( "multiple persisters contained property [" + propertyName + "]" );
+				}
+				persisterReference = test;
+			}
+		}
+		return persisterReference;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class SelectItem extends Node {
+	public Node getSelectExpression() {
+		return ( Node ) getFirstChild();
+	}
+
+	public Node getAlias() {
+		return ( Node ) getFirstChild().getNextSibling();
+	}
+
+	public String getAliasText() {
+		return getAlias() == null ? null : getAlias().getText();
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class SelectStatement extends Node implements Statement {
+	public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext normalizationContext) {
+		return new BasicPathNormalizationStrategySupport( normalizationContext );
+	}
+
+	public QuerySpec locateQuerySpec() {
+		return ( QuerySpec ) getFirstChild();
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+
+/**
+ * Contract for HQL statements.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public interface Statement extends AST {
+	public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext normalizationContext);
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import org.hibernate.HibernateException;
+
+/**
+ * Specialized statement node for representing <tt>UPDATE</tt> statements
+ *
+ * @author Steve Ebersole
+ */
+public class UpdateStatement extends Node implements Statement {
+	public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext normalizationContext) {
+		return new BasicPathNormalizationStrategySupport( normalizationContext ) {
+			protected void validateJoinCreation(PersisterReference origin, String property) {
+				throw new HibernateException(
+						"update statement cannot contain implicit join path expressions"
+				);
+			}
+		};
+	}
+}
\ No newline at end of file

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,422 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.AliasBuilder;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReferenceBuilder;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizeTokenTypes;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import org.hibernate.sql.ast.phase.hql.normalize.DuplicateAliasException;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import antlr.collections.AST;
+import antlr.CommonAST;
+import antlr.Token;
+
+/**
+ * Abstract implementation of {@link PathNormalizationStrategy} providing convenience methods to actual
+ * {@link PathNormalizationStrategy} implementors.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPathNormalizationStrategy implements PathNormalizationStrategy, HqlNormalizeTokenTypes {
+	private static final Logger log = LoggerFactory.getLogger( AbstractPathNormalizationStrategy.class );
+
+	protected final NormalizationContext normalizationContext;
+	private PersisterReference root;  // todo whether we need this depends on how we deciode to structure the prop-joins...
+	private String pathThusFar = null;
+
+	protected AbstractPathNormalizationStrategy(NormalizationContext normalizationContext) {
+		this.normalizationContext = normalizationContext;
+	}
+
+	/**
+	 * Getter for property 'root'.
+	 *
+	 * @return Value for property 'root'.
+	 */
+	protected PersisterReference getRoot() {
+		return root;
+	}
+
+
+	// normalization context ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Getter for property 'normalizationContext'.
+	 *
+	 * @return Value for property 'normalizationContext'.
+	 */
+	protected NormalizationContext getNormalizationContext() {
+		return normalizationContext;
+	}
+
+	protected final AST createNode(int type, String text) {
+		return getNormalizationContext().getASTFactory().create( type, text );
+	}
+
+	/**
+	 * Getter for property 'aliasBuilder'.
+	 *
+	 * @return Value for property 'aliasBuilder'.
+	 */
+	protected final AliasBuilder getAliasBuilder() {
+		return getNormalizationContext().getAliasBuilder();
+	}
+
+	/**
+	 * Getter for property 'persisterReferenceBuilder'.
+	 *
+	 * @return Value for property 'persisterReferenceBuilder'.
+	 */
+	protected final PersisterReferenceBuilder getPersisterReferenceBuilder() {
+		return getNormalizationContext().getPersisterReferenceBuilder();
+	}
+
+	/**
+	 * Getter for property 'sessionFactoryImplementor'.
+	 *
+	 * @return Value for property 'sessionFactoryImplementor'.
+	 */
+	protected final SessionFactoryImplementor getSessionFactoryImplementor() {
+		return getNormalizationContext().getSessionFactoryImplementor();
+	}
+
+	/**
+	 * Getter for property 'ASTPrinter'.
+	 *
+	 * @return Value for property 'ASTPrinter'.
+	 */
+	protected final ASTPrinter getASTPrinter() {
+		return getNormalizationContext().getPrinter();
+	}
+
+
+	// path ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected void initializePathSoFar(String root) {
+		pathThusFar = root;
+	}
+
+	/**
+	 * Getter for property 'pathThusFar'.
+	 *
+	 * @return Value for property 'pathThusFar'.
+	 */
+	public String getPathThusFar() {
+		return pathThusFar;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public final PathedPropertyReferenceSource handleRoot(PersisterReference persisterReference) {
+		initializePathSoFar( persisterReference.getAlias() );
+		root = persisterReference;
+		log.trace( "handling root path source [" + pathThusFar + "]" );
+		return internalHandleRoot( persisterReference );
+	}
+
+	/**
+	 * Hook for subclasses to process the path root.
+	 *
+	 * @param persisterReference The persister defining the source root.
+	 * @return The appropriate property path source implementation.
+	 */
+	protected abstract PathedPropertyReferenceSource internalHandleRoot(PersisterReference persisterReference);
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public final PathedPropertyReferenceSource handleIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+		pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar + "." + pathPart.getText();
+		log.trace( "handling intermediate path source [" + pathThusFar + "]" );
+		return internalResolveIntermediatePathPart( source, pathPart );
+	}
+
+	/**
+	 * Hook for subclasses to process an intermediate part of the path.
+	 *
+	 * @param source The source from which pathPart originates.
+	 * @param pathPart The name of the path part to be processed.
+	 * @return The appropriate property path source implementation.
+	 */
+	protected PathedPropertyReferenceSource internalResolveIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+		return source.handleIntermediatePathPart( pathPart );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public final PropertyReference handleTerminalPathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+		pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar + "." + pathPart.getText();
+		log.trace( "handling terminal path part [" + pathThusFar + "]" );
+		try {
+			return internalResolveTerminalPathPart( source, pathPart );
+		}
+		finally {
+			pathThusFar = null;
+		}
+	}
+
+	/**
+	 * Hook for subclasses to process the terminal (or ending) part of a path.
+	 *
+	 * @param source The source from which pathPart originates.
+	 * @param pathPart The name of the path part to be processed.
+	 * @return a {@link #PROPERTY_REF} node representing the normalized property path.
+	 */
+	protected PropertyReference internalResolveTerminalPathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+		return source.handleTerminalPathPart( pathPart );
+	}
+
+	/**
+	 * Convenience method to locate the index of a component sub-property.  The returned index is relative to
+	 * {@link ComponentType#getPropertyNames}.
+	 *
+	 * @param componentType The component type mapping.
+	 * @param subPropertyName The sub-property name.
+	 * @return The index.
+	 */
+	protected final int locateComponentPropertyIndex(ComponentType componentType, Ident subPropertyName) {
+		return locateComponentPropertyIndex( componentType, subPropertyName.getText() );
+	}
+
+	/**
+	 * Convenience method to locate the index of a component sub-property.  The returned index is relative to
+	 * {@link ComponentType#getPropertyNames}.
+	 *
+	 * @param componentType The component type mapping.
+	 * @param subPropertyName The sub-property name.
+	 * @return The index.
+	 */
+	protected static int locateComponentPropertyIndex(ComponentType componentType, String subPropertyName) {
+		String[] componentPropertyNames = componentType.getPropertyNames();
+		for ( int i = 0; i < componentPropertyNames.length; i++ ) {
+			if ( componentPropertyNames[i].equals( subPropertyName ) ) {
+				return i;
+			}
+		}
+		throw new QueryException( "could not locate component property [" + subPropertyName + "]" );
+	}
+
+	/**
+	 * Generate a {@link #PROPERTY_REF} node.
+	 *
+	 * @param origin The persister from which the property originates.
+	 * @param propertyName The name of the property being referenced.
+	 * @return The {@link #PROPERTY_REF} node.
+	 */
+	protected final PropertyReference generatePropertyReference(PersisterReference origin, String propertyName) {
+		AST propertyReference = createNode( PROPERTY_REF, "property-reference" );
+		propertyReference.addChild( createNode( ALIAS_REF, origin.getAlias() ) );
+		propertyReference.addChild( createNode( IDENT, propertyName ) );
+		return ( PropertyReference ) propertyReference;
+	}
+
+	/**
+	 * Locate (if property joins are reusable) or build an appropriate join.
+	 *
+	 * @param lhs The join lhs, which is the origin of the property.
+	 * @param propertyName The name of the property
+	 * @param alias The alias, if any, to apply to the generated RHS persister reference.
+	 * @param propertyFetching Should property fetching be applied to the generated RHS?
+	 * @param associationFetch Did this property join specify association fetching (join fetch)?
+	 * @return The appropriate join.
+	 */
+	protected final Join locateOrBuildPropertyJoin(
+			PersisterReference lhs,
+			String propertyName,
+			String alias,
+			boolean propertyFetching,
+			boolean associationFetch) {
+		Join join = null;
+
+		if ( areJoinsReusable() ) {
+			join = lhs.locateReusablePropertyJoin( propertyName );
+		}
+
+		if ( join == null ) {
+			join = buildPropertyJoin( lhs, propertyName, alias, propertyFetching, associationFetch );
+			if ( areJoinsReusable() ) {
+				lhs.registerReusablePropertyJoin( propertyName, join );
+			}
+		}
+
+		return join;
+	}
+
+	/**
+	 * Build a property join node.
+	 *
+	 * @param lhs The join's left-hand-side persister-reference
+	 * @param propertyName The property name.
+	 * @param alias The alias to apply to the rhs of the join
+	 * @param propertyFetching should property fetching be applied to the joined persister?
+	 * @param associationFetch Should the association making up the property join also be fetched?
+	 *
+	 * @return The right-hand-side persister-reference.
+	 */
+	protected Join buildPropertyJoin(
+			PersisterReference lhs,
+			String propertyName,
+			String alias,
+			boolean propertyFetching,
+			boolean associationFetch) {
+		validateJoinCreation( lhs, propertyName );
+
+		PersisterReference rhs = null;
+		final Type associationType = lhs.getPropertyType( propertyName );
+		if ( associationType.isCollectionType() ) {
+			CollectionType collectionType = ( CollectionType ) associationType;
+			rhs = getPersisterReferenceBuilder().buildCollectionPersisterReference(
+					collectionType.getRole(),
+					alias,
+					propertyFetching
+			);
+		}
+		else if ( associationType.isEntityType() ) {
+			EntityType entityType = ( EntityType ) associationType;
+			String entityName = entityType.getAssociatedEntityName( getSessionFactoryImplementor() );
+			rhs = getPersisterReferenceBuilder().buildEntityPersisterReference( entityName, alias, propertyFetching );
+		}
+		else {
+			throw new HibernateException( "cannot create join on non-association [name=" + propertyName + ", type=" + associationType + "]" );
+		}
+
+		Join propertyJoinNode = ( Join ) createNode( JOIN, "join" );
+		propertyJoinNode.setFirstChild( buildJoinTypeNode() );
+		propertyJoinNode.addChild( rhs );
+
+		// todo : handle mapped join conditions, adding them to the tree
+
+		if ( associationFetch ) {
+			registerAssociationFetch( propertyJoinNode );
+		}
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					getASTPrinter().showAsString(
+							propertyJoinNode,
+							"implicit join [" + lhs.getAlias() + "." + propertyName + "]"
+					)
+			);
+		}
+
+		lhs.addChild( propertyJoinNode );
+
+		return propertyJoinNode;
+	}
+
+	/**
+	 * Hook to allow subclasses to disallow implicit join.
+	 *
+	 * @param origin The persister-reference which is the origin of the property
+	 * @param property The property resulting in a join.
+	 */
+	protected void validateJoinCreation(PersisterReference origin, String property) {
+		log.debug( "creating path expression implied join [" + origin.getAlias() + "].[" + property + "]" );
+	}
+
+	private void registerAssociationFetch(Join propertyJoinNode) {
+		// todo : implement
+	}
+
+	/**
+	 * Hook to allow subclasses to define the type of join to use for an implciit join.
+	 * <p/>
+	 * The default is to use an {@link #INNER} join.
+	 *
+	 * @return The join type node.
+	 */
+	protected AST buildJoinTypeNode() {
+		return createNode( INNER, "inner" );
+	}
+
+	/**
+	 * Does this strategy allows property joins to be reused?
+	 *
+	 * @return True/false.
+	 */
+	protected boolean areJoinsReusable() {
+		return true;
+	}
+
+
+	// source impl support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public abstract class AbstractPathedPropertyReferenceSource extends CommonAST
+			implements PathedPropertyReferenceSource, DisplayableNode {
+		private final String originationPath;
+
+		/**
+		 * Constructs a new AbstractPathedPropertyReferenceSource.
+		 */
+		protected AbstractPathedPropertyReferenceSource() {
+			this( getPathThusFar() );
+		}
+
+		protected AbstractPathedPropertyReferenceSource(Token token) {
+			this( token, getPathThusFar() );
+		}
+
+		protected AbstractPathedPropertyReferenceSource(String originationPath) {
+			this.originationPath = originationPath;
+		}
+
+		protected AbstractPathedPropertyReferenceSource(Token token, String originationPath) {
+			super( token );
+			this.originationPath = originationPath;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public String getOriginationPath() {
+			return originationPath;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public final String getDisplayText() {
+				return " ADPATER : SHOULD NEVER END UP IN TREE!";
+		}
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,65 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+
+/**
+ * Applies a strategy pattern to the manner in which path expressions are normalized, allowing contextual pluggability
+ * of the implicit-join handling rules...
+ *
+ * @author Steve Ebersole
+ */
+public interface PathNormalizationStrategy {
+	/**
+	 * Handle the root of the pathed property reference path.
+	 *
+	 * @param persisterReference The root of the path.
+	 *
+	 * @return The source representation of the path root.
+	 */
+	public PathedPropertyReferenceSource handleRoot(PersisterReference persisterReference);
+
+	/**
+	 * Handle an intermeidary path part.
+	 *
+	 * @param source The source of the property reference.
+	 * @param pathPart The current property path part.
+	 *
+	 * @return The new source for further property part handling.
+	 */
+	public PathedPropertyReferenceSource handleIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart);
+
+	/**
+	 * Handle the terminal path part.
+	 *
+	 * @param source The source of the property reference.
+	 * @param pathPart The current (and terminal/last) path part.
+	 *
+	 * @return The terminal property reference indicated by the overall path.
+	 */
+	public PropertyReference handleTerminalPathPart(PathedPropertyReferenceSource source, Ident pathPart);
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import java.util.LinkedList;
+
+/**
+ * Provides a stack of {@link PathNormalizationStrategy}s
+ *
+ * @author Steve Ebersole
+ */
+public class PathNormalizationStrategyStack {
+	private LinkedList stack = new LinkedList();
+
+	public void push(PathNormalizationStrategy handler) {
+		stack.addFirst( handler );
+	}
+
+	public PathNormalizationStrategy pop() {
+		return ( PathNormalizationStrategy ) stack.removeFirst();
+	}
+
+	public PathNormalizationStrategy getCurrent() {
+		return ( PathNormalizationStrategy ) stack.getFirst();
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,64 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+
+/**
+ * The contract for representing the non-terminal parts of a property path expression
+ * <p/>
+ * NOTE : extends AST so the grammar can more easily handle it, not because it will actually end up in the syntax
+ * tree (it will not).
+ *
+ * @author Steve Ebersole
+ */
+public interface PathedPropertyReferenceSource extends AST {
+	/**
+	 * Return the path which led to this source.
+	 *
+	 * @return The origination path.
+	 */
+	public String getOriginationPath();
+
+	/**
+	 * Handle an intermediate path part reference.
+	 *
+	 * @param name The name for the path part to handle.
+	 *
+	 * @return An appropriate source representation of said intermeidate path part.
+	 */
+	public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name);
+
+	/**
+	 * Handle the terminal path reference.
+	 *
+	 * @param name The name of the terminal path part.
+	 *
+	 * @return The property reference.
+	 */
+	public PropertyReference handleTerminalPathPart(Ident name);
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,255 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import org.hibernate.sql.ast.phase.hql.normalize.path.AbstractPathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.type.Type;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.EntityType;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.HibernateException;
+import org.hibernate.hql.CollectionProperties;
+
+/**
+ * Basic {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy}.  Mainly used as the
+ * basis for other implementations.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicPathNormalizationStrategySupport extends AbstractPathNormalizationStrategy {
+	private static final Logger log = LoggerFactory.getLogger( BasicPathNormalizationStrategySupport.class );
+
+	public BasicPathNormalizationStrategySupport(NormalizationContext normalizationContext) {
+		super( normalizationContext );
+	}
+
+	protected PathedPropertyReferenceSource internalHandleRoot(PersisterReference persisterReference) {
+		return new RootSourceImpl( persisterReference );
+	}
+
+	private PathedPropertyReferenceSource determineAppropriateIntermediateSourceType(PersisterReference origin, Ident propertyName) {
+		final String propertyNameText = propertyName.getText();
+		final Type propertyType = origin.getPropertyType( propertyNameText );
+		if ( propertyType.isComponentType() ) {
+			return new ComponentIntermediatePathSource( origin, propertyNameText, ( ComponentType ) propertyType );
+		}
+		else if ( propertyType.isEntityType() ) {
+			return new EntityIntermediatePathSource( origin, propertyNameText );
+		}
+		else if ( propertyType.isCollectionType() ) {
+			return new CollectionIntermediatePathSource( origin, propertyNameText );
+		}
+		else {
+			return new SimpleIntermediatePathSource();
+		}
+	}
+
+	/**
+	 * Is the given property name a reference to the primary key of the associated
+	 * entity construed by the given entity type?
+	 * <p/>
+	 * For example, consider a fragment like order.customer.id
+	 * (where order is a from-element alias).  Here, we'd have:
+	 * propertyName = "id" AND
+	 * owningType = ManyToOneType(Customer)
+	 * and are being asked to determine whether "customer.id" is a reference
+	 * to customer's PK...
+	 *
+	 * @param propertyName The name of the property to check.
+	 * @param owningType The type represeting the entity "owning" the property
+	 * @return True if propertyName references the enti ty's (owningType->associatedEntity)
+	 * primary key; false otherwise.
+	 */
+	private boolean isReferenceToPrimaryKey(EntityType owningType, String propertyName) {
+		EntityPersister persister = getSessionFactoryImplementor().getEntityPersister(
+				owningType.getAssociatedEntityName( getSessionFactoryImplementor() )
+		);
+		if ( persister.getEntityMetamodel().hasNonIdentifierPropertyNamedId() ) {
+			// only the identifier property field name can be a reference to the associated entity's PK...
+			return propertyName.equals( persister.getIdentifierPropertyName() ) && owningType.isReferenceToPrimaryKey();
+		}
+		else {
+			// here, we have two possibilities:
+			// 		1) the property-name matches the explicitly identifier property name
+			//		2) the property-name matches the implicit 'id' property name
+			if ( EntityPersister.ENTITY_ID.equals( propertyName ) ) {
+				// the referenced node text is the special 'id'
+				return owningType.isReferenceToPrimaryKey();
+			}
+			else {
+				String keyPropertyName = owningType.getIdentifierOrUniqueKeyPropertyName( getSessionFactoryImplementor() );
+				return keyPropertyName != null && keyPropertyName.equals( propertyName ) && owningType.isReferenceToPrimaryKey();
+			}
+		}
+	}
+
+
+
+	// source impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	private class RootSourceImpl extends AbstractPathedPropertyReferenceSource {
+		private final PersisterReference lhs;
+
+		public RootSourceImpl(PersisterReference lhs) {
+			this.lhs = lhs;
+		}
+
+		public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+			return determineAppropriateIntermediateSourceType( lhs, name );
+		}
+
+		public PropertyReference handleTerminalPathPart(Ident name) {
+			final String nameText = name.getText();
+			if ( lhs.getPropertyType( nameText ).isEntityType() ) {
+				if ( shouldTerminalEntityPropertyForceJoin() ) {
+					locateOrBuildPropertyJoin( lhs, nameText, null, false, false );
+				}
+			}
+			return generatePropertyReference( lhs, name.getText() );
+		}
+
+		public String getText() {
+			return "root-source {" + lhs.getAlias() + "}";
+		}
+	}
+
+	protected class SimpleIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+		public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+			throw new HibernateException( "cannot dereference simple value as part of path expression" );
+		}
+
+		public PropertyReference handleTerminalPathPart(Ident name) {
+			throw new HibernateException( "cannot dereference simple value as part of path expression" );
+		}
+	}
+
+	private class ComponentIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+		private final PersisterReference lhs;
+		private final String propertyPath;
+		private final ComponentType componentType;
+
+		public ComponentIntermediatePathSource(PersisterReference lhs, String propertyPath) {
+			this( lhs, propertyPath, ( ComponentType ) lhs.getPropertyType( propertyPath ) );
+		}
+
+		private ComponentIntermediatePathSource(PersisterReference lhs, String propertyPath, ComponentType componentType) {
+			this.lhs = lhs;
+			this.propertyPath = propertyPath;
+			this.componentType = componentType;
+		}
+
+		public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+			final String propertyName = name.getText();
+			final int index = locateComponentPropertyIndex( componentType, propertyName );
+			final String path = buildComponentDereferencePath( propertyName );
+			final Type propertyType = componentType.getSubtypes()[index];
+			if ( propertyType.isComponentType() ) {
+				return new ComponentIntermediatePathSource( lhs, path, ( ComponentType ) propertyType );
+			}
+			else if ( propertyType.isEntityType() ) {
+				return new EntityIntermediatePathSource( lhs, path );
+			}
+			else {
+				return new SimpleIntermediatePathSource();
+			}
+		}
+
+		public PropertyReference handleTerminalPathPart(Ident name) {
+			return generatePropertyReference( lhs, buildComponentDereferencePath( name.getText() ) );
+		}
+
+		private String buildComponentDereferencePath(String subPropertyName) {
+			return propertyPath + "." + subPropertyName;
+		}
+	}
+
+	protected class EntityIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+		private final PersisterReference lhs;
+		private final String lhsPropertyName;
+
+		public EntityIntermediatePathSource(PersisterReference lhs, String lhsPropertyName) {
+			this.lhs = lhs;
+			this.lhsPropertyName = lhsPropertyName;
+		}
+
+		public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+			Join join = locateOrBuildPropertyJoin( lhs, lhsPropertyName, null, false, false );
+			return determineAppropriateIntermediateSourceType( join.getRhs(), name );
+		}
+
+		public PropertyReference handleTerminalPathPart(Ident name) {
+			final EntityType type = ( EntityType ) lhs.getPropertyType( lhsPropertyName );
+			if ( isReferenceToPrimaryKey( type, lhsPropertyName ) ) {
+				return generatePropertyReference( lhs, lhsPropertyName + "." + name.getText() );
+			}
+			else {
+				Join join = locateOrBuildPropertyJoin( lhs, lhsPropertyName, null, false, false );
+				final String propertyName = name.getText();
+				if ( type.isEntityType() ) {
+					if ( shouldTerminalEntityPropertyForceJoin() ) {
+						locateOrBuildPropertyJoin( join.getRhs(), propertyName, null, false, false );
+					}
+				}
+				return generatePropertyReference( join.getRhs(), propertyName );
+			}
+		}
+	}
+
+	protected boolean shouldTerminalEntityPropertyForceJoin() {
+		return false;
+	}
+
+	protected class CollectionIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+		private final PersisterReference lhs;
+		private final String propertyName;
+
+		public CollectionIntermediatePathSource(PersisterReference lhs, String propertyName) {
+			this.lhs = lhs;
+			this.propertyName = propertyName;
+		}
+
+		public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+			throw new HibernateException( "cannot implicit join across a collection association" );
+		}
+
+		public PropertyReference handleTerminalPathPart(Ident name) {
+			// TODO : what are the circusmstances under which we need to *join* to the collection, as opposed to say munge it into a subquery???
+			final String nameText = name.getText();
+			if ( CollectionProperties.isAnyCollectionProperty( nameText ) ) {
+				Join join = locateOrBuildPropertyJoin( lhs, propertyName, null, false, false );
+				return generatePropertyReference( join.getRhs(), nameText );
+			}
+			throw new HibernateException( "cannot implicit join across a collection association" );
+		}
+	}
+}
\ No newline at end of file

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,128 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizeTokenTypes;
+import org.hibernate.sql.ast.phase.hql.normalize.path.AbstractPathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.type.Type;
+import org.hibernate.HibernateException;
+import org.hibernate.QueryException;
+
+/**
+ *
+ * {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} for dealing with path expressions
+ * occuring in the <tt>FROM</tt> clause of a query.
+ *
+ * @author Steve Ebersole
+ */
+public class FromClausePathNormalizationStrategy extends AbstractPathNormalizationStrategy
+		implements PathNormalizationStrategy, HqlNormalizeTokenTypes {
+
+	private final JoinType joinType;
+	private final boolean associationFetch;
+	private final boolean propertyFetch;
+	private final String alias;
+
+
+	/**
+	 * Instantiate a normalization strategy for handling path expressions in a <tt>FROM</tt> clause.
+	 *
+	 * @param normalizationContext The context for normalization.
+	 * @param joinType The type of explicit-join specified at the root of this path expression.
+	 * @param associationFetch Was association fetching indicated on this path expression?
+	 * @param propertyFetch Was property fetching indicated on this path expression?
+	 * @param alias The alias (if one) specified on this joined path expression.
+	 */
+	public FromClausePathNormalizationStrategy(
+			NormalizationContext normalizationContext,
+			JoinType joinType,
+			boolean associationFetch,
+			boolean propertyFetch,
+			String alias) {
+		super( normalizationContext );
+		this.joinType = joinType;
+		this.associationFetch = associationFetch;
+		this.propertyFetch = propertyFetch;
+		this.alias = alias;
+	}
+
+	protected PathedPropertyReferenceSource internalHandleRoot(PersisterReference persisterReference) {
+		return new SourceImpl( persisterReference );
+	}
+
+	private class SourceImpl extends AbstractPathedPropertyReferenceSource {
+		private final PersisterReference lhs;
+
+		private SourceImpl(PersisterReference lhs) {
+			this.lhs = lhs;
+		}
+
+		public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+			// TODO : still need to account for paths including component dereferences...
+			return new SourceImpl( locateOrBuildPropertyJoin( lhs, name.getText(), null, false, associationFetch ).getRhs() );
+		}
+
+		public PropertyReference handleTerminalPathPart(Ident name) {
+			final String propertyName = name.getText();
+			Type terminalPropertyType = lhs.getPropertyType( propertyName );
+			if ( !terminalPropertyType.isAssociationType() ) {
+				throw new HibernateException( "non-association type cannot be used as termination of path expression in from clause" );
+			}
+
+			locateOrBuildPropertyJoin( lhs, name.getText(), alias, propertyFetch, associationFetch );
+
+			PropertyReference propertyReference = generatePropertyReference( lhs, name.getText() );
+			propertyReference.injectOriginalPath( getPathThusFar() );
+
+			return propertyReference;
+		}
+	}
+
+	protected AST buildJoinTypeNode() {
+		if ( joinType == JoinType.INNER ) {
+			return createNode( INNER, "inner" );
+		}
+		else if ( joinType == JoinType.LEFT ) {
+			return createNode( LEFT, "left" );
+		}
+		else if ( joinType == JoinType.RIGHT ) {
+			return createNode( RIGHT, "right" );
+		}
+		// if no match found, throw exception
+		throw new QueryException( "Unrecognized join type [" + joinType.toString() + "]" );
+	}
+
+	protected boolean areJoinsReusable() {
+		return false;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.HibernateException;
+
+/**
+ * {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} for dealing with path expressions
+ * occuring in the <tt>ON</tt> clause of a persister join.
+ *
+ * @author Steve Ebersole
+ */
+public class OnFragmentPathNormalizationStrategy extends BasicPathNormalizationStrategySupport {
+	private final PersisterReference joinRhs;
+	private PersisterReference joinLhs;
+
+	public OnFragmentPathNormalizationStrategy(NormalizationContext resolutionContext, PersisterReference joinRhs) {
+		super( resolutionContext );
+		this.joinRhs = joinRhs;
+	}
+
+	public PersisterReference getDiscoveredLHS() {
+		return joinLhs;
+	}
+
+	protected PathedPropertyReferenceSource internalHandleRoot(PersisterReference persisterReference) {
+		// persisterReference must either refer to our LHS or RHS...
+		if ( persisterReference == joinRhs ) {
+			// nothing to do...
+		}
+		else if ( joinLhs != null ) {
+			if ( persisterReference != joinLhs ) {
+				throw new HibernateException(
+						"path root not resolveable against either left-hand-side [" +
+						joinLhs.getText() + "] nor right-hand-side [" +
+						joinRhs.getText() + "] of the join"
+				);
+			}
+		}
+		else {
+			joinLhs = persisterReference;
+		}
+		return super.internalHandleRoot( persisterReference );
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+
+/**
+ * Essentially the same stragety as {@link BasicPathNormalizationStrategySupport} expcept that in the select clause
+ * an entity encountered as the terminal part must force a join...
+ * <p/>
+ * todo : the above is true as long as the path is not a function argument...
+ *
+ * @author Steve Ebersole
+ */
+public class SelectClausePathNormalizationStrategy extends BasicPathNormalizationStrategySupport {
+
+	public SelectClausePathNormalizationStrategy(NormalizationContext normalizationContext) {
+		super( normalizationContext );
+	}
+
+	protected boolean shouldTerminalEntityPropertyForceJoin() {
+		// here we should *as long as* we are not part of a function processing
+		return ! getNormalizationContext().isCurrentlyProcessingFunction();
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,77 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import org.hibernate.HibernateException;
+import org.hibernate.QueryException;
+
+import antlr.collections.AST;
+
+/**
+ * {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} for dealing with <tt>WITH</tt>
+ * fragments used to supply addition join conditions to property joins.
+ *
+ * @author Steve Ebersole
+ */
+public class WithFragmentPathNormalizationStrategy extends BasicPathNormalizationStrategySupport {
+	public static final Log log = LogFactory.getLog( WithFragmentPathNormalizationStrategy.class );
+
+	private final PersisterReference lhs;
+
+	public WithFragmentPathNormalizationStrategy(NormalizationContext normalizationContext, PersisterReference lhs) {
+		super( normalizationContext );
+		this.lhs = lhs;
+	}
+
+	public void applyWithFragment(AST withFragment) {
+		PersisterReference rhs = getRoot();
+		// first, locate the actual Join node which links the lhs and rhs...
+		Join join = null;
+		AST nextPossible = lhs.getFirstChild();
+		while ( nextPossible != null ) {
+			if ( nextPossible instanceof Join ) {
+				if ( ( ( Join ) nextPossible ).getRhs() == rhs ) {
+					join = ( Join ) nextPossible;
+					break;
+				}
+			}
+			nextPossible = nextPossible.getNextSibling();
+		}
+		if ( join == null ) {
+			throw new QueryException( "could not locate specific join node to which to apply with fragment [" + withFragment + "]" );
+		}
+		join.addChild( withFragment );
+	}
+
+	protected void validateJoinCreation(PersisterReference origin, String property) {
+		// todo : why not???
+		throw new HibernateException( "Path expression [" + origin.getText() + "].[" + property + "] within 'with clause' cannot result in physical join" );
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java (from rev 15693, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/HqlParser.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,609 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.parse;
+
+import org.hibernate.sql.ast.util.ASTUtil;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.util.ErrorCounter;
+import org.hibernate.sql.ast.util.ParseErrorHandler;
+import org.hibernate.QueryException;
+import org.hibernate.MappingException;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.sql.ast.common.CommonHibernateLexer;
+import org.hibernate.sql.ast.common.TokenImpl;
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.NodeFactory;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.StringReader;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import antlr.collections.AST;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+import antlr.Token;
+import antlr.ASTPair;
+import antlr.MismatchedTokenException;
+import antlr.SemanticException;
+import antlr.ASTFactory;
+
+/**
+ * The parser used by Hibernate to generate an AST given an input HQL string (a "stream parser").  The produced
+ * AST is then used (and mutated) by later phases/parsers to apply semantic resolution; this parser, however, is
+ * all about syntax resolution.
+ *
+ * @author Steve Ebersole
+ */
+public class HqlParser extends GeneratedHqlParser {
+	private static final Logger log = LoggerFactory.getLogger( HqlParser.class );
+
+	private final Context context;
+	private final ParseErrorHandler parseErrorHandler = new ErrorCounter();
+	private final ASTPrinter printer = new ASTPrinter( HqlParseTokenTypes.class );
+	private int traceDepth = 0;
+
+	public HqlParser(String hql, Context context) {
+		super( new CommonHibernateLexer( new StringReader( hql ) ) );
+		this.context = context;
+		super.setASTFactory( new NodeFactory() );
+	}
+
+	public HqlParser(String hql, final SessionFactoryImplementor sessionFactoryImplementor) {
+		this( hql, wrapInContext( sessionFactoryImplementor ) );
+	}
+
+	// overrides of Antlr infastructure methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void reportError(RecognitionException e) {
+		parseErrorHandler.reportError( e );
+	}
+
+	public void reportError(String s) {
+		parseErrorHandler.reportError( s );
+	}
+
+	public void reportWarning(String s) {
+		parseErrorHandler.reportWarning( s );
+	}
+
+	public ParseErrorHandler getParseErrorHandler() {
+		return parseErrorHandler;
+	}
+
+	static public void panic() {
+		//overriden to avoid System.exit
+		throw new QueryException( "Parser: panic" );
+	}
+
+	public void setASTFactory(ASTFactory astFactory) {
+		throw new UnsupportedOperationException( "not allowed!" );
+	}
+
+
+// various AST output methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void traceIn(String s) throws TokenStreamException {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = StringHelper.repeat( "-", (traceDepth++ * 2) ) + "->";
+		trace( prefix + s );
+	}
+
+	public void traceOut(String s) throws TokenStreamException {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = "<-" + StringHelper.repeat( "-", (--traceDepth * 2) );
+		trace( prefix + s );
+	}
+
+    private void trace(String msg) {
+		System.out.println( msg );
+//		log.trace( msg );
+	}
+
+	public void dumpAst(AST ast) {
+		dumpAst( ast, "DUMP" );
+	}
+
+	public void dumpAst(AST ast, String header) {
+		log.info( printer.showAsString( ast, header ) );
+	}
+
+	public void showAst(AST ast, PrintStream out) {
+		showAst( ast, new PrintWriter( out ) );
+	}
+
+	private void showAst(AST ast, PrintWriter pw) {
+		printer.showAst( ast, pw );
+	}
+
+
+	// overrides of grammar semantic actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public String extractPath(AST tree) {
+		try {
+			return PathCollector.getPath( tree );
+		}
+		catch ( Throwable t ) {
+			return tree.getText();
+		}
+	}
+
+	public boolean isRegisteredFunction(AST tree) {
+		return context.isRegisteredFunctionName( extractPath( tree ) );
+	}
+
+	public boolean isJavaConstant(String path) {
+		try {
+			log.debug( "Testing path [" + path + "] as potential java constant" );
+			Object value = ReflectHelper.getConstantValueStrictly( path );
+			log.debug( "Resolved path to java constant [" + value + "]" );
+			return true;
+		}
+		catch( Throwable t ) {
+			log.debug( "Path did not resolve to java constant : " + t );
+			return false;
+		}
+	}
+
+	public String resolveEntityName(String name) {
+		return context.getImportedName( name );
+	}
+
+	public String resolveDynamicInstantiationPojoName(AST name) throws SemanticException {
+		String path = extractPath( name );
+		if ( "list".equals( path ) || "map".equals( path ) ) {
+			return path;
+		}
+		else {
+			String importedName = context.getImportedName( path );
+			try {
+				Class importedClass = ReflectHelper.classForName( importedName );
+				return importedClass.getName();
+			}
+			catch ( ClassNotFoundException e ) {
+				throw new SemanticException( "Unable to locate dynamic instantiation class [" + importedName + "]" );
+			}
+		}
+	}
+
+	protected AST processEqualityExpression(AST x) {
+		if ( x == null ) {
+			log.warn( "processEqualityExpression() : No expression to process!" );
+			return null;
+		}
+
+		int type = x.getType();
+		if ( log.isTraceEnabled() ) {
+			log.trace( "processEqualityExpression() -> type : {}, name : {}", Integer.toString( type ), ASTUtil.getTokenTypeName( HqlParseTokenTypes.class, type ) );
+		}
+		if ( type == EQUALS_OP || type == NOT_EQUALS_OP || type == SQL_NOT_EQUALS_OP ) {
+			boolean negated = ( type != EQUALS_OP );
+			if ( x.getNumberOfChildren() == 2 ) {
+				AST a = x.getFirstChild();
+				AST b = a.getNextSibling();
+				// (EQ NULL b) => (IS_NULL b)
+				if ( a.getType() == NULL && b.getType() != NULL ) {
+					return createIsNullParent( b, negated );
+				}
+				// (EQ a NULL) => (IS_NULL a)
+				else if ( b.getType() == NULL && a.getType() != NULL ) {
+					return createIsNullParent( a, negated );
+				}
+				else if ( b.getType() == EMPTY ) {
+					return processIsEmpty( a, negated );
+				}
+				else {
+					return x;
+				}
+			}
+			else {
+				return x;
+			}
+		}
+		else {
+			return x;
+		}
+	}
+
+	private AST createIsNullParent(AST node, boolean negated) {
+		node.setNextSibling( null );
+		int type = negated ? IS_NOT_NULL : IS_NULL;
+		String text = negated ? "is not null" : "is null";
+		return ASTUtil.createParent( astFactory, type, text, node );
+	}
+
+	protected AST processMemberOf(AST path, AST notNode) {
+		AST inNode = notNode == null ? astFactory.create( IN, "in" ) : astFactory.create( NOT_IN, "not in" );
+		AST subqueryNode = createSubquery( path );
+		AST inListNode = ASTUtil.createParent( astFactory, IN_LIST, "in-list", subqueryNode );
+		inNode.addChild( inListNode );
+		return inNode;
+	}
+
+	private AST createSubquery(AST subquerySource) {
+//		AST ast = ASTUtil.createParent( astFactory, RANGE, "RANGE", node );
+// todo : what is the type of 'node'?
+		log.debug(
+				"Generating subquery; incoming node type = {}; incoming node = [{}]",
+				printer.getTokenTypeName( subquerySource.getType() ),
+				subquerySource
+		);
+		AST fromNode = ASTUtil.createParent( astFactory, FROM, "from", subquerySource );
+		AST selectFromNode = ASTUtil.createParent( astFactory, SELECT_FROM, "SELECT_FROM", fromNode );
+		return ASTUtil.createParent( astFactory, QUERY, "QUERY", selectFromNode );
+	}
+
+	protected AST processIsEmpty(AST collection, AST notToken) {
+		return processIsEmpty( collection, notToken != null );
+	}
+
+	private AST processIsEmpty(AST node, boolean negated) {
+		node.setNextSibling( null );
+		AST ast = createSubquery( node );
+		ast = ASTUtil.createParent( astFactory, EXISTS, "exists", ast );
+		// Add NOT if it's negated.
+		if ( negated ) {
+			ast = ASTUtil.createParent( astFactory, NOT, "not", ast );
+		}
+		return ast;
+	}
+	public AST negateNode(AST x) {
+		//TODO: switch statements are always evil! We already had bugs because
+		//      of forgotten token types. Use polymorphism for this!
+		switch ( x.getType() ) {
+			case OR:
+				x.setType(AND);
+				x.setText("{and}");
+				negateNode( x.getFirstChild() );
+				negateNode( x.getFirstChild().getNextSibling() );
+				return x;
+			case AND:
+				x.setType(OR);
+				x.setText("{or}");
+				negateNode( x.getFirstChild() );
+				negateNode( x.getFirstChild().getNextSibling() );
+				return x;
+			case EQUALS_OP:
+				x.setType( NOT_EQUALS_OP );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (EQ a b) ) => (NE a b)
+			case NOT_EQUALS_OP:
+				x.setType( EQUALS_OP );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (NE a b) ) => (EQ a b)
+			case GREATER_THAN_OP:
+				x.setType( LESS_THAN_OR_EQUALS_OP );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (GT a b) ) => (LE a b)
+			case LESS_THAN_OP:
+				x.setType( GREATER_THAN_OR_EQUALS_OP );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (LT a b) ) => (GE a b)
+			case GREATER_THAN_OR_EQUALS_OP:
+				x.setType( LESS_THAN_OP );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (GE a b) ) => (LT a b)
+			case LESS_THAN_OR_EQUALS_OP:
+				x.setType( GREATER_THAN_OP );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (LE a b) ) => (GT a b)
+			case LIKE:
+				x.setType( NOT_LIKE );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (LIKE a b) ) => (NOT_LIKE a b)
+			case NOT_LIKE:
+				x.setType( LIKE );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (NOT_LIKE a b) ) => (LIKE a b)
+			case IN:
+				x.setType( NOT_IN );
+				x.setText( "{not}" + x.getText() );
+				return x;
+			case NOT_IN:
+				x.setType( IN );
+				x.setText( "{not}" + x.getText() );
+				return x;
+			case IS_NULL:
+				x.setType( IS_NOT_NULL );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (IS_NULL a b) ) => (IS_NOT_NULL a b)
+			case IS_NOT_NULL:
+				x.setType( IS_NULL );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (IS_NOT_NULL a b) ) => (IS_NULL a b)
+			case BETWEEN:
+				x.setType( NOT_BETWEEN );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (BETWEEN a b) ) => (NOT_BETWEEN a b)
+			case NOT_BETWEEN:
+				x.setType( BETWEEN );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (NOT_BETWEEN a b) ) => (BETWEEN a b)
+			case NOT:
+				return x.getFirstChild();			// (NOT (NOT x) ) => (x)
+			default:
+				return super.negateNode( x );		// Just add a 'not' parent.
+		}
+	}
+
+	protected void transferTrackingInfo(AST source, AST target) {
+		if ( target instanceof Node ) {
+			( ( Node ) target ).transferTrackingInfo( source );
+		}
+		else {
+			super.transferTrackingInfo( source, target );
+		}
+	}
+
+	/**
+	 * Overrides the base behavior to retry keywords as identifiers.
+	 *
+	 * @param token The token.
+	 * @param ex    The recognition exception.
+	 * @return AST - The new AST.
+	 * @throws antlr.RecognitionException if the substitution was not possible.
+	 * @throws antlr.TokenStreamException if the substitution was not possible.
+	 */
+	public AST handleIdentifierError(Token token, RecognitionException ex) throws RecognitionException, TokenStreamException {
+		// If the token can tell us if it could be an identifier...
+		if ( token instanceof TokenImpl ) {
+			TokenImpl hqlToken = ( TokenImpl ) token;
+			// ... and the token could be an identifer and the error is
+			// a mismatched token error ...
+			if ( hqlToken.isPossibleIdentifier() && ex instanceof MismatchedTokenException ) {
+				MismatchedTokenException mte = ( MismatchedTokenException ) ex;
+				// ... and the expected token type was an identifier, then:
+				if ( mte.expecting == IDENT ) {
+					// Use the token as an identifier.
+					reportWarning(
+							"Keyword  '"+ token.getText()
+							+ "' is being interpreted as an identifier due to: "
+							+ mte.getMessage()
+					);
+					// Add the token to the AST.
+					ASTPair currentAST = new ASTPair();
+//					token.setType( WEIRD_IDENT );
+					token.setType( IDENT );
+					astFactory.addASTChild( currentAST, astFactory.create( token ) );
+					consume();
+					return currentAST.root;
+				}
+			}
+		}
+		return super.handleIdentifierError( token, ex );
+	}
+
+    public void handleDotIdent() throws TokenStreamException {
+        // This handles HHH-354, where there is a strange property name in a where clause.
+        // If the lookahead contains a DOT then something that isn't an IDENT...
+		handleDotIdent( 1 );
+    }
+
+	protected int handleDotIdent(int offset) throws TokenStreamException {
+		while ( LA( offset ) == DOT ) {
+			switch ( LA( offset+1 ) ) {
+				case IDENT:
+				case CLASS:
+					break; // break the case statement, not the loop...
+				default:
+					convertPossibleIdentifier( ( TokenImpl ) LT( offset+1 ) );
+			}
+			offset += 2;
+		}
+		return offset;
+	}
+
+	protected void weakKeywords() throws TokenStreamException {
+		switch ( LA( 1 ) ) {
+			case IDENT:
+				break;
+			default :
+				if ( LA(0) == FROM && LA(2) == DOT ) {
+					convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+				}
+		}
+	}
+
+	protected void unequivocalKeywordAsIdentifier() throws TokenStreamException {
+		if ( LA(1) == IDENT ) {
+			return;
+		}
+		convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+	}
+
+    protected void potentialUpdatePersisterAlias() throws TokenStreamException {
+		switch( LA(1) ) {
+			case AS:
+				// alias rule will handle this...
+			case SET:
+				// SET marks the beginning of the UPDATE's SET-clause
+				break;
+			default:
+				convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+		}
+	}
+
+    protected void potentialDeletePersisterAlias() throws TokenStreamException {
+		switch( LA(1) ) {
+			case AS:
+				// alias rule will handle this...
+			case WHERE:
+				break;
+			default:
+				convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+		}
+    }
+
+    protected void prepareForPersisterReferenceRoot() throws TokenStreamException {
+		if ( LA(1) == IN ) {
+			return;
+		}
+
+		unequivocalKeywordAsIdentifier();
+
+		if ( LA(1) == IDENT && LA(2) == IN ) {
+			return;
+		}
+
+		prepareForBasicEntityPersisterReference();
+	}
+
+    protected void prepareForCrossJoinElements() throws TokenStreamException {
+		unequivocalKeywordAsIdentifier();
+		prepareForBasicEntityPersisterReference();
+    }
+
+	protected void prepareForBasicEntityPersisterReference() throws TokenStreamException {
+		int offset = handleDotIdent( 2 );
+		int next = LA(offset);
+		switch ( next ) {
+			case AS: {
+				// the next token would need to be the persister alias
+				convertPossibleIdentifier( (TokenImpl) LT(offset+1) );
+				break;
+			}
+			case IDENT : {
+				// nothing to do
+				break;
+			}
+			case WHERE:
+			case COMMA:
+			case ON:
+			case WITH:
+			case JOIN:
+			case RIGHT:
+			case LEFT:
+			case CROSS: {
+				// single token structural elements indicating that the next thing could not be an alias
+				break;
+			}
+			case UNION:
+			case INTERSECT:
+			case EXCEPT: {
+				int nextNext = LA(offset+1);
+				if ( nextNext == SELECT || nextNext == FROM ) {
+					break;
+				}
+				else if ( nextNext == ALL ) {
+					int nextNextNext = LA(offset+2);
+					if ( nextNextNext == SELECT || nextNextNext == FROM ) {
+						break;
+					}
+				}
+				convertPossibleIdentifier( ( TokenImpl ) LT(offset) );
+				break;
+			}
+			case FETCH:
+				if ( ! ( LA(offset+1) == ALL && LA(offset+2) == PROPERTIES ) ) {
+					// not sure sure I like allowing 'fetch' as an indentifier
+					log.warn( "interpretting [fetch] keyword as alias; consider using differen alias" );
+					convertPossibleIdentifier( ( TokenImpl ) LT(offset) );
+				}
+				break;
+			default:
+				convertPossibleIdentifier( ( TokenImpl ) LT(offset) );
+				break;
+		}
+	}
+
+	protected void prepareForQualifiedJoinElements() throws TokenStreamException {
+		unequivocalKeywordAsIdentifier();
+		prepareForBasicEntityPersisterReference();
+    }
+
+	protected void convertPossibleIdentifier(TokenImpl token) {
+		if ( token.isPossibleIdentifier() && token.getType() != IDENT ) {
+			log.debug( "Converting keyword [{}] to identifier", printer.getTokenTypeName( token.getType() ) );
+			token.setType( IDENT );
+		}
+	}
+
+	private static Context wrapInContext(final SessionFactoryImplementor sessionFactoryImplementor) {
+		return new Context() {
+			public boolean isEntityName(String name) {
+				return findEntityPersisterByName( name ) != null;
+			}
+
+			public String getImportedName(String name) {
+				return sessionFactoryImplementor.getImportedClassName( name );
+			}
+
+			public boolean isRegisteredFunctionName(String name) {
+				return sessionFactoryImplementor.getDialect().getFunctions().get( name ) != null;
+			}
+
+			private EntityPersister findEntityPersisterByName(String name) throws MappingException {
+				try {
+					return sessionFactoryImplementor.getEntityPersister( name );
+				}
+				catch ( MappingException ignore ) {
+					// unable to locate it using this name
+				}
+
+				// If that didn't work, try using the 'import' name.
+				String importedClassName = sessionFactoryImplementor.getImportedClassName( name );
+				if ( importedClassName == null ) {
+					return null;
+				}
+				return sessionFactoryImplementor.getEntityPersister( importedClassName );
+			}
+		};
+	}
+
+	public static interface Context {
+		/**
+		 * Does this name represent an entity name?
+		 *
+		 * @param name The name to check
+		 * @return True if the name represents an entioty name; false otherwise.
+		 */
+		public boolean isEntityName(String name);
+
+		/**
+		 * Get the import "replacement" name for the given name (e.g., 'User' -> 'com.acme.User').  <tt>null</tt>
+		 * indicates an unrecognized name.
+		 *
+		 * @param name The name for which to locate the imported name.
+		 * @return The corresponding imported name, or null.
+		 */
+		public String getImportedName(String name);
+
+		/**
+		 * Does the given name represent a registered function name?
+		 *
+		 * @param name The name to check
+		 * @return True if the name matches a registered function name; false otherwise.
+		 */
+		public boolean isRegisteredFunctionName(String name);
+	}
+}

Copied: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java (from rev 15693, core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/PathCollector.java)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,61 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.parse;
+
+import antlr.collections.AST;
+
+/**
+ * Utilizes a NodeTraverser in order to collect a path from
+ * (expecting dot-structure) an AST.
+ *
+ * @author Steve Ebersole
+ */
+public class PathCollector implements HqlParseTokenTypes {
+
+	/**
+	 * Direct instantiation of PathCollector disallowed.
+	 */
+	private PathCollector() {
+	}
+
+	public static String getPath(AST dotStructure) {
+		if ( dotStructure.getType() == IDENT ) {
+			return dotStructure.getText();
+		}
+
+		return extractText( dotStructure );
+	}
+
+	private static String extractText(AST node) {
+		AST lhs = node.getFirstChild();
+		AST rhs = lhs.getNextSibling();
+
+		if ( lhs.getType() == IDENT ) {
+			return lhs.getText() + node.getText() + rhs.getText();
+		}
+		else {
+			return extractText( lhs ) + node.getText() + rhs.getText();
+		}
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.util;
+
+import java.util.Iterator;
+
+import antlr.collections.AST;
+
+/**
+ * Iteration of an AST tree bounded to a given level of children.
+ *
+ * @author Steve Ebersole
+ */
+public class ASTChildIterator implements Iterator {
+
+	private AST next;
+
+	public ASTChildIterator(AST next) {
+		this.next = next;
+	}
+
+	public boolean hasNext() {
+		return next != null;
+	}
+
+	public Object next() {
+		AST rtn = next;
+		next = next.getNextSibling();
+		return rtn;
+	}
+
+	public void remove() {
+		throw new UnsupportedOperationException( "remove() is not supported" );
+	}
+}

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -26,7 +26,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Map;
 
@@ -215,8 +214,7 @@
         }
     }
 
-    public static String escapeMultibyteChars(String text)
-    {
+    public static String escapeMultibyteChars(String text) {
         StringBuffer buf = new StringBuffer();
         appendEscapedMultibyteChars(text,buf);
         return buf.toString();

Added: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.util;
+
+import antlr.collections.AST;
+import antlr.ASTFactory;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class NodeDeepCopier {
+	private final ASTFactory astFactory;
+
+	public NodeDeepCopier(ASTFactory astFactory) {
+		this.astFactory = astFactory;
+	}
+
+	public AST copy(AST node) {
+		AST newNode = createShallowCopy( node );
+		AST child = node.getFirstChild();
+		while ( child != null ) {
+			newNode.addChild( copy( child ) );
+			child = child.getNextSibling();
+		}
+		return newNode;
+	}
+
+	public AST createShallowCopy(AST node) {
+		AST newNode = astFactory.create( node.getType(), node.getText() );
+		newNode.initialize( node );
+		return newNode;
+	}
+}

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -32,6 +32,7 @@
 import org.hibernate.AssertionFailure;
 import org.hibernate.MappingException;
 import org.hibernate.PropertyNotFoundException;
+import org.hibernate.HibernateException;
 import org.hibernate.property.BasicPropertyAccessor;
 import org.hibernate.property.DirectPropertyAccessor;
 import org.hibernate.property.Getter;
@@ -276,6 +277,24 @@
 		}
 	}
 
+	public static Object getConstantValueStrictly(String name) {
+		String className = StringHelper.qualifier( name );
+		String fieldName = StringHelper.unqualify( name );
+		try {
+			Class clazz = classForName( className );
+			return clazz.getField( fieldName ).get( null );
+		}
+		catch ( ClassNotFoundException cnfe ) {
+			throw new HibernateException( "Could not locate class containing constant [" + className + "]" );
+		}
+		catch ( IllegalAccessException e ) {
+			throw new HibernateException( "Could not access specified field [" + name + "]" );
+		}
+		catch ( NoSuchFieldException e ) {
+			throw new HibernateException( "Could not locate specified filed [" + name + "]" );
+		}
+	}
+
 	/**
 	 * Retrieve the default (no arg) constructor from the given class.
 	 *

Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -27,6 +27,7 @@
 import java.util.Iterator;
 import java.util.StringTokenizer;
 import java.util.ArrayList;
+import java.util.Arrays;
 
 public final class StringHelper {
 
@@ -85,6 +86,11 @@
 		return buf.toString();
 	}
 
+	public static String repeat(char character, int times) {
+		char[] buffer = new char[times];
+		Arrays.fill( buffer, character );
+		return new String( buffer );
+	}
 
 	public static String replace(String template, String placeholder, String replacement) {
 		return replace( template, placeholder, replacement, false );

Modified: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -31,7 +31,7 @@
 import org.hibernate.persister.entity.PropertyMapping;
 import org.hibernate.type.Type;
 import org.hibernate.QueryException;
-import org.hibernate.sql.ordering.antlr.ColumnMapper;
+import org.hibernate.sql.ast.ordering.ColumnMapper;
 import org.hibernate.dialect.Dialect;
 import org.hibernate.dialect.HSQLDialect;
 import org.hibernate.dialect.function.SQLFunctionRegistry;

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,77 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * Implementation of Address.
+ *
+ * @author Steve Ebersole
+ */
+public class Address {
+	private String street;
+	private String city;
+	private String postalCode;
+	private String country;
+	private StateProvince stateProvince;
+
+	public String getStreet() {
+		return street;
+	}
+
+	public void setStreet(String street) {
+		this.street = street;
+	}
+
+	public String getCity() {
+		return city;
+	}
+
+	public void setCity(String city) {
+		this.city = city;
+	}
+
+	public String getPostalCode() {
+		return postalCode;
+	}
+
+	public void setPostalCode(String postalCode) {
+		this.postalCode = postalCode;
+	}
+
+	public String getCountry() {
+		return country;
+	}
+
+	public void setCountry(String country) {
+		this.country = country;
+	}
+
+	public StateProvince getStateProvince() {
+		return stateProvince;
+	}
+
+	public void setStateProvince(StateProvince stateProvince) {
+		this.stateProvince = stateProvince;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,121 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * @author Gavin King
+ */
+public class Animal {
+	private Long id;
+	private float bodyWeight;
+	private Set offspring;
+	private Animal mother;
+	private Animal father;
+	private String description;
+	private Zoo zoo;
+	private String serialNumber;
+
+	public Animal() {
+	}
+
+	public Animal(String description, float bodyWeight) {
+		this.description = description;
+		this.bodyWeight = bodyWeight;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public float getBodyWeight() {
+		return bodyWeight;
+	}
+
+	public void setBodyWeight(float bodyWeight) {
+		this.bodyWeight = bodyWeight;
+	}
+
+	public Set getOffspring() {
+		return offspring;
+	}
+
+	public void addOffspring(Animal offspring) {
+		if ( this.offspring == null ) {
+			this.offspring = new HashSet();
+		}
+
+		this.offspring.add( offspring );
+	}
+
+	public void setOffspring(Set offspring) {
+		this.offspring = offspring;
+	}
+
+	public Animal getMother() {
+		return mother;
+	}
+
+	public void setMother(Animal mother) {
+		this.mother = mother;
+	}
+
+	public Animal getFather() {
+		return father;
+	}
+
+	public void setFather(Animal father) {
+		this.father = father;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public Zoo getZoo() {
+		return zoo;
+	}
+
+	public void setZoo(Zoo zoo) {
+		this.zoo = zoo;
+	}
+
+	public String getSerialNumber() {
+		return serialNumber;
+	}
+
+	public void setSerialNumber(String serialNumber) {
+		this.serialNumber = serialNumber;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,30 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Cat extends DomesticAnimal {
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,101 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * Mimic a JDK 5 enum.
+ *
+ * @author Steve Ebersole
+ */
+public class Classification implements Serializable, Comparable {
+
+	public static final Classification COOL = new Classification( "COOL", 0 );
+	public static final Classification LAME = new Classification( "LAME", 1 );
+
+	private static final HashMap INSTANCES = new HashMap();
+	static {
+		INSTANCES.put( COOL.name, COOL );
+		INSTANCES.put( LAME.name, LAME );
+	}
+
+	private final String name;
+	private final int ordinal;
+	private final int hashCode;
+
+	private Classification(String name, int ordinal) {
+		this.name = name;
+		this.ordinal = ordinal;
+
+		int hashCode = name.hashCode();
+		hashCode = 29 * hashCode + ordinal;
+		this.hashCode = hashCode;
+	}
+
+	public String name() {
+		return name;
+	}
+
+	public int ordinal() {
+		return ordinal;
+	}
+
+	public boolean equals(Object obj) {
+		return compareTo( obj ) == 0;
+	}
+
+	public int compareTo(Object o) {
+		int otherOrdinal = ( ( Classification ) o ).ordinal;
+		if ( ordinal == otherOrdinal ) {
+			return 0;
+		}
+		else if ( ordinal > otherOrdinal ) {
+			return 1;
+		}
+		else {
+			return -1;
+		}
+	}
+
+	public int hashCode() {
+		return hashCode;
+	}
+
+	public static Classification valueOf(String name) {
+		return ( Classification ) INSTANCES.get( name );
+	}
+
+	public static Classification valueOf(Integer ordinal) {
+		if ( ordinal == null ) {
+			return null;
+		}
+		switch ( ordinal.intValue() ) {
+			case 0: return COOL;
+			case 1: return LAME;
+			default: throw new IllegalArgumentException( "unknown classification ordinal [" + ordinal + "]" );
+		}
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,124 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import org.hibernate.usertype.EnhancedUserType;
+import org.hibernate.HibernateException;
+import org.hibernate.Hibernate;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+import java.io.Serializable;
+
+/**
+ * A custom type for mapping {@link Classification} instances
+ * to the respective db column.
+ * </p>
+ * THis is largely intended to mimic JDK5 enum support in JPA.  Here we are
+ * using the approach of storing the ordinal values, rather than the names.
+ *
+ * @author Steve Ebersole
+ */
+public class ClassificationType implements EnhancedUserType {
+
+	public int[] sqlTypes() {
+		return new int[] { Types.TINYINT };
+	}
+
+	public Class returnedClass() {
+		return Classification.class;
+	}
+
+	public boolean equals(Object x, Object y) throws HibernateException {
+		if ( x == null && y == null ) {
+			return false;
+		}
+		else if ( x != null ) {
+			return x.equals( y );
+		}
+		else {
+			return y.equals( x );
+		}
+	}
+
+	public int hashCode(Object x) throws HibernateException {
+		return x.hashCode();
+	}
+
+	public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+		Integer ordinal = ( Integer ) Hibernate.INTEGER.nullSafeGet( rs, names[0] );
+		return Classification.valueOf( ordinal );
+	}
+
+	public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		Integer ordinal = value == null ? null : new Integer( ( ( Classification ) value ).ordinal() );
+		Hibernate.INTEGER.nullSafeSet( st, ordinal, index );
+	}
+
+	public Object deepCopy(Object value) throws HibernateException {
+		return value;
+	}
+
+	public boolean isMutable() {
+		return false;
+	}
+
+	public Serializable disassemble(Object value) throws HibernateException {
+		return ( Classification ) value;
+	}
+
+	public Object assemble(Serializable cached, Object owner) throws HibernateException {
+		return cached;
+	}
+
+	public Object replace(Object original, Object target, Object owner) throws HibernateException {
+		return original;
+	}
+
+	public String objectToSQLString(Object value) {
+		return extractOrdinalString( value );
+	}
+
+	public String toXMLString(Object value) {
+		return extractName( value );
+	}
+
+	public Object fromXMLString(String xmlValue) {
+		return Classification.valueOf( xmlValue );
+	}
+
+	private String extractName(Object obj) {
+		return ( ( Classification ) obj ).name();
+	}
+
+	private int extractOrdinal(Object value) {
+		return ( ( Classification ) value ).ordinal();
+	}
+
+	private String extractOrdinalString(Object value) {
+		return Integer.toString( extractOrdinal( value ) );
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,30 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Dog extends DomesticAnimal {
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class DomesticAnimal extends Mammal {
+	private Human owner;
+
+	public Human getOwner() {
+		return owner;
+	}
+
+	public void setOwner(Human owner) {
+		this.owner = owner;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Gavin King
+ */
+public class Human extends Mammal {
+	private Name name;
+	private String nickName;
+	private Collection friends;
+	private Collection pets;
+	private Map family;
+	private double height;
+	
+	private BigInteger bigIntegerValue;
+	private BigDecimal bigDecimalValue;
+	private int intValue;
+	private float floatValue;
+	
+	private Set nickNames;
+	private Map addresses;
+
+	public Collection getFriends() {
+		return friends;
+	}
+
+	public void setFriends(Collection friends) {
+		this.friends = friends;
+	}
+
+	public Collection getPets() {
+		return pets;
+	}
+
+	public void setPets(Collection pets) {
+		this.pets = pets;
+	}
+
+	public Name getName() {
+		return name;
+	}
+
+	public void setName(Name name) {
+		this.name = name;
+	}
+
+	public String getNickName() {
+		return nickName;
+	}
+
+	public void setNickName(String nickName) {
+		this.nickName = nickName;
+	}
+	
+	public double getHeight() {
+		return height;
+	}
+	public void setHeight(double height) {
+		this.height = height;
+	}
+
+	public Map getFamily() {
+		return family;
+	}
+	
+
+	public void setFamily(Map family) {
+		this.family = family;
+	}
+
+	public Set getNickNames() {
+		return nickNames;
+	}
+
+	public void setNickNames(Set nickNames) {
+		this.nickNames = nickNames;
+	}
+
+	public Map getAddresses() {
+		return addresses;
+	}
+
+	public void setAddresses(Map addresses) {
+		this.addresses = addresses;
+	}
+
+	public BigDecimal getBigDecimalValue() {
+		return bigDecimalValue;
+	}
+
+	public void setBigDecimalValue(BigDecimal bigDecimalValue) {
+		this.bigDecimalValue = bigDecimalValue;
+	}
+
+	public BigInteger getBigIntegerValue() {
+		return bigIntegerValue;
+	}
+
+	public void setBigIntegerValue(BigInteger bigIntegerValue) {
+		this.bigIntegerValue = bigIntegerValue;
+	}
+
+	public float getFloatValue() {
+		return floatValue;
+	}
+
+	public void setFloatValue(float floatValue) {
+		this.floatValue = floatValue;
+	}
+
+	public int getIntValue() {
+		return intValue;
+	}
+
+	public void setIntValue(int intValue) {
+		this.intValue = intValue;
+	}
+	
+	
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * Implementation of Joiner.
+ *
+ * @author Steve Ebersole
+ */
+public class Joiner {
+	private Long id;
+	private String name;
+	private String joinedName;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getJoinedName() {
+		return joinedName;
+	}
+
+	public void setJoinedName(String joinedName) {
+		this.joinedName = joinedName;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,31 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Lizard extends Reptile {
+
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.util.Date;
+
+/**
+ * @author Gavin King
+ */
+public class Mammal extends Animal {
+	private boolean pregnant;
+	private Date birthdate;
+
+	public boolean isPregnant() {
+		return pregnant;
+	}
+
+	public void setPregnant(boolean pregnant) {
+		this.pregnant = pregnant;
+	}
+
+	public Date getBirthdate() {
+		return birthdate;
+	}
+	
+
+	public void setBirthdate(Date birthdate) {
+		this.birthdate = birthdate;
+	}
+	
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,166 @@
+<?xml version="1.0"?>
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.sql.ast.phase.hql.domain" default-access="field">
+
+	<class name="Animal">
+		<id name="id">
+			<generator class="native"/>
+		</id>
+		<property name="description"/>
+		<property name="bodyWeight" column="body_weight"/>
+		<many-to-one name="mother" column="mother_id"/>
+		<many-to-one name="father" column="father_id"/>
+		<many-to-one name="zoo" column="zoo_id"/>
+		<property name="serialNumber"/>
+		<set name="offspring" order-by="father_id">
+			<key column="mother_id"/>
+			<one-to-many class="Animal"/>
+		</set>
+		<joined-subclass name="Reptile">
+			<key column="animal"/>
+			<property name="bodyTemperature"/>
+			<joined-subclass name="Lizard">
+				<key column="reptile"/>
+			</joined-subclass>
+		</joined-subclass>
+		<joined-subclass name="Mammal">
+			<key column="animal"/>
+			<property name="pregnant"/>
+			<property name="birthdate" type="date"/>
+			<joined-subclass name="DomesticAnimal">
+				<key column="mammal"/>
+				<many-to-one name="owner"/>
+				<joined-subclass name="Cat">
+					<key column="mammal"/>
+				</joined-subclass>
+				<joined-subclass name="Dog">
+					<key column="mammal"/>
+				</joined-subclass>
+			</joined-subclass>
+			<joined-subclass name="Human">
+				<key column="mammal"/>
+				<component name="name">
+					<property name="first" column="name_first"/>
+					<property name="initial" column="name_initial"/>
+					<property name="last" column="name_last"/>
+				</component>
+				<property name="nickName"/>
+				<property name="height"/>
+				<bag name="friends">
+					<key column="human1"/>
+					<many-to-many column="human2" class="Human"/>
+				</bag>
+				<map name="family">
+					<key column="human1"/>
+					<map-key column="relationship" type="string"/>
+					<many-to-many column="human2" class="Human"/>
+				</map>
+				<bag name="pets" inverse="true">
+					<key column="owner"/>
+					<one-to-many class="DomesticAnimal"/>
+				</bag>
+				<set name="nickNames" lazy="false" table="human_nick_names" sort="natural">
+					<key column="human"/>
+					<element column="nick_name" type="string" not-null="true"/>
+				</set>
+				<map name="addresses" table="addresses">
+					<key column="human"/>
+					<map-key type="string" column="type"/>
+					<composite-element class="Address">
+						<property name="street"/>
+						<property name="city"/>
+						<property name="postalCode"/>
+						<property name="country"/>
+                        <many-to-one name="stateProvince" column="state_prov_id" class="StateProvince"/>
+					</composite-element>
+				</map>
+			</joined-subclass>
+		</joined-subclass>
+	</class>
+<!--
+	<class name="User" table="`User`">
+		<id name="id">
+			<generator class="foreign">
+				<param name="property">human</param>
+			</generator>
+		</id>
+		<property name="userName"/>
+		<one-to-one name="human" constrained="true"/>
+		<list name="permissions">
+			<key column="userId"/>
+			<list-index column="permissionId"/>
+			<element type="string" column="permissionName"/>
+		</list>
+	</class>
+-->
+	<class name="Zoo" discriminator-value="Z">
+		<id name="id">
+			<generator class="native"/>
+		</id>
+		<discriminator column="zooType" type="character"/>
+		<property name="name" type="string"/>
+        <property name="classification" type="org.hibernate.sql.ast.phase.hql.domain.ClassificationType"/>
+		<map name="mammals">
+			<key column="mammalZoo_id"/>
+			<index type="string" column="name"/>
+			<one-to-many class="Mammal"/>
+		</map>
+		<map name="animals" inverse="true">
+			<key column="zoo_id"/>
+			<index type="string" column="serialNumber"/>
+			<one-to-many class="Animal"/>
+		</map>
+        <component name="address" class="Address">
+            <property name="street"/>
+            <property name="city"/>
+            <property name="postalCode"/>
+            <property name="country"/>
+            <many-to-one name="stateProvince" column="state_prov_id" class="StateProvince"/>
+        </component>
+		<subclass name="PettingZoo" discriminator-value="P"/>
+	</class>
+
+    <class name="StateProvince">
+        <id name="id">
+            <generator class="native"/>
+        </id>
+        <property name="name"/>
+        <property name="isoCode"/>
+    </class>
+
+	<class name="Joiner">
+		<id name="id">
+			<generator class="native"/>
+		</id>
+		<property name="name"/>
+		<join table="JOINED">
+			<key column="ID"/>
+			<property name="joinedName"/>
+		</join>
+	</class>
+
+</hibernate-mapping>
\ No newline at end of file

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Name {
+	private String first;
+	private Character initial;
+	private String last;
+	
+	protected Name() {}
+	
+	public Name(String first, Character initial, String last) {
+		this.first = first;
+		this.initial = initial;
+		this.last = last;
+	}
+
+	public Name(String first, char initial, String last) {
+		this( first, new Character( initial ), last );
+	}
+
+	public String getFirst() {
+		return first;
+	}
+
+	public void setFirst(String first) {
+		this.first = first;
+	}
+
+	public Character getInitial() {
+		return initial;
+	}
+
+	public void setInitial(Character initial) {
+		this.initial = initial;
+	}
+
+	public String getLast() {
+		return last;
+	}
+
+	public void setLast(String last) {
+		this.last = last;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,30 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class PettingZoo extends Zoo {
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,37 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Reptile extends Animal {
+	private float bodyTemperature;
+	public float getBodyTemperature() {
+		return bodyTemperature;
+	}
+	public void setBodyTemperature(float bodyTemperature) {
+		this.bodyTemperature = bodyTemperature;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * Implementation of StateProvince.
+ *
+ * @author Steve Ebersole
+ */
+public class StateProvince {
+	private Long id;
+	private String name;
+	private String isoCode;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getIsoCode() {
+		return isoCode;
+	}
+
+	public void setIsoCode(String isoCode) {
+		this.isoCode = isoCode;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,86 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.util.Map;
+
+/**
+ * @author Gavin King
+ */
+public class Zoo {
+	private Long id;
+	private String name;
+	private Classification classification;
+	private Map animals;
+	private Map mammals;
+	private Address address;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Map getMammals() {
+		return mammals;
+	}
+
+	public void setMammals(Map mammals) {
+		this.mammals = mammals;
+	}
+
+	public Map getAnimals() {
+		return animals;
+	}
+
+	public void setAnimals(Map animals) {
+		this.animals = animals;
+	}
+
+	public Address getAddress() {
+		return address;
+	}
+
+	public void setAddress(Address address) {
+		this.address = address;
+	}
+
+	public Classification getClassification() {
+		return classification;
+	}
+
+	public void setClassification(Classification classification) {
+		this.classification = classification;
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,356 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.sql.ast.util.NodeTraverser;
+import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizer;
+import org.hibernate.sql.ast.phase.hql.normalize.QuerySpec;
+import org.hibernate.sql.ast.phase.hql.normalize.SelectItem;
+import org.hibernate.sql.ast.phase.hql.normalize.SelectStatement;
+import org.hibernate.sql.ast.phase.hql.parse.ParserTest;
+import org.hibernate.sql.ast.phase.hql.domain.Animal;
+import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.hql.QuerySplitter;
+
+import antlr.collections.AST;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class NormalizerTest extends TestCase implements HqlNormalizeTokenTypes {
+	private SessionFactoryImplementor sessionFactory;
+
+	protected void setUp() throws Exception {
+		super.setUp();
+		sessionFactory = ( SessionFactoryImplementor ) new Configuration()
+				.setProperty( Environment.HBM2DDL_AUTO, "none" )
+				.setProperty( Environment.DIALECT, HSQLDialect.class.getName() )
+				.addResource( "org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml" )
+				.buildSessionFactory();
+	}
+
+	protected void tearDown() throws Exception {
+		if ( sessionFactory != null ) {
+			sessionFactory.close();
+		}
+		super.tearDown();
+	}
+
+	public void testBasicStructure() throws Throwable {
+		AST query = resolve( "select a from Animal a order by a.name" );
+		assertEquals( query.getType(), QUERY );
+
+		AST querySpec = query.getFirstChild();
+		assertEquals( QUERY_SPEC, querySpec.getType() );
+
+		AST selectFrom = querySpec.getFirstChild();
+		assertEquals( SELECT_FROM, selectFrom.getType() );
+
+		AST from = selectFrom.getFirstChild();
+		assertEquals( FROM, from.getType() );
+		assertSame( from, ( ( QuerySpec ) querySpec ).locateFromClause() );
+
+		AST select = from.getNextSibling();
+		assertEquals( SELECT, select.getType() );
+		assertSame( select, ( ( QuerySpec ) querySpec ).locateSelectClause() );
+
+		assertEquals( SELECT_LIST, select.getFirstChild().getType() );
+		assertEquals( SELECT_ITEM, select.getFirstChild().getFirstChild().getType() );
+
+		AST sorting = querySpec.getNextSibling();
+		assertEquals( ORDER_BY, sorting.getType() );
+
+	}
+
+	public void testSimpleHql() throws Exception {
+		// First, get an AST by parsing some HQL text.
+		AST ast = resolve( "from Animal" );
+		// Assert:
+		assertEquals( ast.getType(), QUERY );
+	}
+
+	public void testSimpleExplicitJoins() throws Throwable {
+		AST ast = resolve( "from Animal as a inner join a.mother as m" );
+		JoinCounter.assertJoinCount( 1, ast );
+
+		ast = resolve( "from Animal as a inner join a.offspring as c inner join a.mother as m" );
+		JoinCounter.assertJoinCount( 2, ast );
+	}
+
+	public void testPathedExplicitJoins() throws Throwable {
+		AST ast = resolve( "from Animal as a inner join a.mother.father.offspring as auntsanduncles" );
+		JoinCounter.assertJoinCount( 3, ast );
+	}
+
+	public void testSelectPersisterReference() throws Throwable {
+		AST query = resolve( "select a from Animal a" );
+		JoinCounter.assertJoinCount( 0, query );
+		SelectItemCounter.assertSelectItemCount( 1, query );
+
+		assertEquals( query.getType(), QUERY );
+		AST selectClause = query.getFirstChild().getFirstChild().getFirstChild().getNextSibling();
+		assertNotNull( selectClause );
+		assertEquals( SELECT, selectClause.getType() );
+		AST selectItem = selectClause.getFirstChild().getFirstChild();
+		assertEquals( SELECT_ITEM, selectItem.getType() );
+		AST aliasRef = selectItem.getFirstChild();
+		assertEquals( ALIAS_REF, aliasRef.getType() );
+		assertEquals( "a", aliasRef.getText() );
+	}
+
+	public void testSelectAssociationPropertyReference() throws Throwable {
+		// todo : implicit joins...
+		AST query = resolve( "select a.mother as m from Animal as a" );
+		JoinCounter.assertJoinCount( 1, query );
+
+		assertTrue( query instanceof SelectStatement );
+		QuerySpec querySpec = ( ( SelectStatement ) query ).locateQuerySpec();
+		AST persisterSpace = querySpec.locateFromClause().getFirstChild();
+		assertEquals( PERSISTER_SPACE, persisterSpace.getType() );
+		EntityPersisterReference entityPersisterReference = ( EntityPersisterReference ) persisterSpace.getFirstChild();
+		Iterator itr = entityPersisterReference.locateJoins();
+		assertTrue( itr.hasNext() );
+		Join join = ( Join ) itr.next();
+		assertFalse( itr.hasNext() );
+		assertEquals( JoinType.INNER, join.getEnumeratedJoinType() );
+		PersisterReference rhs = join.getRhs();
+		assertEquals( Animal.class.getName(), rhs.getName() );
+		// this should work since there is only one non-explicit persister alias...
+		assertEquals( "<gen:0>", rhs.getAlias() );
+
+		SelectItemCounter.assertSelectItemCount( 1, query );
+		AST selectList = querySpec.locateSelectClause().getFirstChild();
+		assertEquals( SELECT_LIST, selectList.getType() );
+		assertEquals( 1, selectList.getNumberOfChildren() );
+		SelectItem selectItem = ( SelectItem ) selectList.getFirstChild();
+		assertEquals( "m", selectItem.getAliasText() );
+		PropertyReference propertyReference = ( PropertyReference ) selectItem.getSelectExpression();
+		assertEquals( ALIAS_REF, propertyReference.getFirstChild().getType() );
+		assertEquals( "a", propertyReference.getFirstChild().getText() );
+		assertEquals( "a.mother", propertyReference.getNormalizedPath() );
+	}
+
+	public void testSimpleSimplePropertyReference() throws Throwable {
+		AST query = resolve( "select a.name as m from Animal as a" );
+		JoinCounter.assertJoinCount( 0, query );
+		SelectItemCounter.assertSelectItemCount( 1, query );
+		assertTrue( query instanceof SelectStatement );
+		AST selectClause = ( ( QuerySpec ) query.getFirstChild() ).locateSelectClause();
+		assertNotNull( selectClause );
+		assertEquals( SELECT, selectClause.getType() );
+		assertEquals( 1, selectClause.getNumberOfChildren() );
+		AST selectList = selectClause.getFirstChild();
+		assertEquals( SELECT_LIST, selectList.getType() );
+		assertEquals( 1, selectList.getNumberOfChildren() );
+		AST selectItem = selectList.getFirstChild();
+		assertEquals( SELECT_ITEM, selectItem.getType() );
+		AST selectExpression = selectItem.getFirstChild();
+		assertEquals( PROPERTY_REF, selectExpression.getType() );
+		PropertyReference propertyReference = ( PropertyReference ) selectExpression;
+		assertEquals( "a.name", propertyReference.getNormalizedPath() );
+		assertEquals( "m", ( ( SelectItem ) selectItem ).getAliasText() );
+	}
+
+	public void testSelectPropertyRefCount() throws Throwable {
+		AST query = resolve( "select count(a.mother) from Animal as a" );
+		JoinCounter.assertJoinCount( 0, query );
+		SelectItemCounter.assertSelectItemCount( 1, query );
+		assertTrue( query instanceof SelectStatement );
+		AST selectClause = ( ( QuerySpec ) query.getFirstChild() ).locateSelectClause();
+		assertNotNull( selectClause );
+		assertEquals( SELECT, selectClause.getType() );
+		assertEquals( 1, selectClause.getNumberOfChildren() );
+		AST selectList = selectClause.getFirstChild();
+		assertEquals( SELECT_LIST, selectList.getType() );
+		assertEquals( 1, selectList.getNumberOfChildren() );
+		AST selectItem = selectList.getFirstChild();
+		assertEquals( SELECT_ITEM, selectItem.getType() );
+		AST selectExpression = selectItem.getFirstChild();
+		assertEquals( COUNT, selectExpression.getType() );
+		assertEquals( "count", selectExpression.getText() );
+	}
+
+	public void testExplicitImplicitJoin() throws Exception {
+		AST ast = resolve( "from Animal a left join fetch a.mother.mother.mother as ggm where ggm.name like '%weeble%'" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 3, ast );
+
+		ast = resolve( "from Animal as a inner join a.mother.mother as gm" );
+		JoinCounter.assertJoinCount( 2, ast );
+
+		ast = resolve( "from Animal as a inner join a.mother.father as gf" );
+		JoinCounter.assertJoinCount( 2, ast );
+
+		ast = resolve( "from Animal as a inner join a.offspring as c inner join a.mother.father as mgf inner join fetch a.father" );
+		JoinCounter.assertJoinCount( 4, ast );
+	}
+
+	public void testExplicitCollectionJoin() throws Throwable {
+		AST ast = resolve( "from Animal as a inner join a.offspring as o where o.name like '%boots%'" );
+	}
+
+	public void testSimpleImplicitJoin() throws Exception {
+		AST ast = resolve( "from Animal a where a.mother.name like '%mary%'" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 1, ast );
+
+		ast = resolve( "from Animal a where a.mother.father.name like '%weeble%'" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 2, ast );
+
+		ast = resolve( "from Animal a where a.mother.mother.name like '%weeble%'" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 2, ast );
+
+		ast = resolve( "from Animal a where a.mother.mother = ?" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 1, ast );
+	}
+
+	public void testWithClause() throws Throwable {
+		resolve( "from Zoo z inner join z.mammals as m with m.name = ?" );
+	}
+
+	public void testUnqualifiedPropertyReference() throws Exception {
+		AST ast = resolve( "from Animal where name like '%mary%'" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 0, ast );
+
+		ast = resolve( "from Animal where mother.name like '%mary%'" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 1, ast );
+	}
+
+	public void testThetaJoins() throws Exception {
+		AST ast = resolve( "from Animal a, Animal b where a.mother.id = b.id and b.name like '%mary%'" );
+		assertTrue( ast instanceof SelectStatement );
+//		JoinCounter.assertJoinCount( 1, ast );
+
+		ast = resolve( "from Animal a, Animal b inner join b.mother as c where a.mother.id = b.id and b.name like '%mary%'" );
+		assertTrue( ast instanceof SelectStatement );
+//		JoinCounter.assertJoinCount( 2, ast );
+	}
+
+	public void testAdHocJoins() throws Exception {
+		resolve( "from Animal a inner join Zoo z on a.id = z.id" );
+		resolve( "from Animal a inner join Zoo z on a.id = z.id inner join z.mammals as m with m.name = ?" );
+	}
+
+	public void testReusingImplcitJoins() throws Throwable {
+		AST ast = resolve( "from Animal a where a.mother.father.name = 'abc' and a.mother.father.description = 'xyz'" );
+		assertTrue( ast instanceof SelectStatement );
+		JoinCounter.assertJoinCount( 2, ast );
+	}
+
+	public void testIndexOperations() throws Throwable {
+//		resolve( "select o from IndexedCollectionOwner as o where o.simpleMap['test'] = 'xyz'" );
+		resolve( "select o from IndexedCollectionOwner as o inner join o.simpleMap as s where o.simpleMap[ index(s) ] = 'xyz'" );
+	}
+
+	public void testIndexOperations2() throws Throwable {
+		resolve( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] = an" );
+		resolve( "from Zoo where mammals['dog'] = ?" );
+		resolve( "from Zoo zoo where zoo.mammals['dog'].father.description like '%black%'" );
+	}
+
+
+	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	private AST resolve(String hql) throws RecognitionException, TokenStreamException {
+		// to be completely accurate, the incoming hql string should be run through
+		// QuerySplitter as that is what happens prior to translation and results in
+		// a different string to actually translate...
+		String[] queries = QuerySplitter.concreteQueries( hql, getSessionFactoryImplementor() );
+		assertEquals( "polymorhpic queries not allowed here", 1, queries.length );
+		hql = queries[0];
+
+		AST hqlAst = ParserTest.doParse( hql, false );
+
+		// Now, pass it though the resolver phase, which yeilds
+		// a processed HQL AST.
+		HqlNormalizer resolver = new HqlNormalizer( sessionFactory );
+		resolver.statement( hqlAst );
+		AST resolvedHql = resolver.getAST();
+		System.out.println( resolver.getPrinter().showAsString( resolvedHql, "Resolved AST  :  " + resolvedHql.toStringTree() + "" ) );
+		return resolvedHql;
+	}
+
+	protected SessionFactoryImplementor getSessionFactoryImplementor() {
+		return sessionFactory;
+	}
+
+	private static class JoinCounter implements NodeTraverser.VisitationStrategy {
+		int count = 0;
+		public void visit(AST node) {
+			if ( node.getType() == JOIN ) {
+				count++;
+			}
+		}
+		public static void assertJoinCount(int expected, AST tree) {
+			JoinCounter.assertJoinCount( "unexpected join count", expected, tree );
+		}
+		public static void assertJoinCount(String failMessage, int expected, AST tree) {
+			JoinCounter counter = new JoinCounter();
+			NodeTraverser walker = new NodeTraverser( counter );
+			walker.traverseDepthFirst( tree );
+			assertEquals( failMessage, expected, counter.count );
+		}
+	}
+
+	private static class SelectItemCounter implements NodeTraverser.VisitationStrategy {
+		int count;
+		public void visit(AST node) {
+			if ( node instanceof SelectItem ) {
+				count++;
+			}
+		}
+		public static void assertSelectItemCount(int expected, AST tree) {
+			SelectItemCounter.assertSelectItemCount( "unexpected select expression count", expected, tree );
+		}
+		public static void assertSelectItemCount(String failMessage, int expected, AST tree) {
+			SelectItemCounter counter = new SelectItemCounter();
+			NodeTraverser walker = new NodeTraverser( counter );
+			walker.traverseDepthFirst( tree );
+			assertEquals( failMessage, expected, counter.count );
+		}
+	}
+
+	public static Test suite() {
+		return new TestSuite( NormalizerTest.class );
+	}
+}

Added: core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java	2009-01-06 20:11:13 UTC (rev 15747)
@@ -0,0 +1,1176 @@
+package org.hibernate.sql.ast.phase.hql.parse;
+
+import junit.framework.TestCase;
+import org.hibernate.sql.ast.util.ASTIterator;
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.phase.hql.parse.HqlParser;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import antlr.collections.AST;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+
+/**
+ * todo: describe ParserTest
+ *
+ * @author Steve Ebersole
+ */
+public class ParserTest extends TestCase implements HqlParseTokenTypes {
+	public static final Log log = LogFactory.getLog( ParserTest.class );
+
+	public static final String CONSTANT = "constant-value";
+
+	public void testEntityReferenceRule() throws Throwable {
+		String entityName = "com.acme.EntityName";
+		HqlParser parser = buildHqlParser( entityName  );
+		parser.entityName();
+		AST result = parser.getAST();
+		show( result, "entity-name-result" );
+		assertEquals( ENTITY_NAME, result.getType() );
+		assertEquals( entityName, result.getText() );
+
+		entityName = "EntityName";
+		parser = buildHqlParser( entityName  );
+		parser.entityName();
+		result = parser.getAST();
+		show( result, "entity-name-result" );
+		assertEquals( ENTITY_NAME, result.getType() );
+		assertEquals( entityName, result.getText() );
+	}
+
+	public void testSimpleFrom() throws Throwable {
+		String entityName = "com.acme.EntityName";
+		HqlParser parser = buildHqlParser( "from " + entityName + " e" );
+		parser.statement();
+		AST result = parser.getAST();
+		show( result, "simple-from-result" );
+	}
+
+	public void testConstantUsage() throws Throwable {
+		HqlParser parser = buildHqlParser( "from com.acme.EntityName where prop = org.hibernate.sql.ast.phase.hql.parse.ParserTest.CONSTANT" );
+		parser.statement();
+		AST result = parser.getAST();
+		show( result, "constant" );
+		AST constantNode = goToWhereClause( result ).getFirstChild().getFirstChild().getNextSibling();
+		assertEquals( JAVA_CONSTANT, constantNode.getType() );
+
+		// apply control checks
+		parser = buildHqlParser( "from com.acme.EntityName where prop = compProp.subProp" );
+		parser.statement();
+		result = parser.getAST();
+		show( result, "constant-control" );
+		AST checkNode = goToWhereClause( result ).getFirstChild().getFirstChild().getNextSibling();
+		assertEquals( DOT, checkNode.getType() );
+	}
+
+	public AST goToWhereClause(AST query) {
+		return query.getFirstChild() 	// QUERY_SPEC
+				.getFirstChild()		// SELECT_FROM
+				.getNextSibling();		// WHERE
+	}
+
+	public void testVariousPropertyReferences() throws Exception {
+		parse( "from A a where b = 1" );
+		parse( "from A a where a.b.c = 1" );
+		parse( "from X x where y[1].z = 2" );
+		parse( "from X x where x.y[1].z = 2" );
+	}
+
+	public void testEntityNamePathWithKeyword() throws Exception {
+		parse( "from org.hibernate.test.Inner" );
+	}
+
+	public void testWhereClauseIdentPrimaryWithEmbeddedKeyword() throws Exception {
+		parse( "from org.hibernate.test.Inner i where i.outer.inner.middle = 'xyz'" );
+	}
+
+	public void testDynamicInstantiation() throws Exception {
+		parse( "select new list(a, mate) from Animal a join a.mate as mate" );
+		parse( "select new Family(mother, mate, offspr) from eg.DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr" );
+	}
+
+	public void testListOrMapKeywordReference() throws Exception {
+		parse( "select p from eg.NameList nl, eg.Person p where p.name = some elements(nl.names)" );
+		parse( "select p from eg.NameList list, eg.Person p where p.name = some elements(list.names)" );
+		parse( "select p from eg.NameList map, eg.Person p where p.name = some elements(map.names)" );
+	}
+
+	public void testExplicitPropertyJoin() throws Exception {
+		parse( "from eg.Cat as cat inner join fetch cat.mate as m fetch all properties left join fetch cat.kittens as k" );
+	}
+
+	private static void show(AST node, String header) {
+		ASTPrinter printer = new ASTPrinter( HqlParseTokenTypes.class, false );
+		log.info( printer.showAsString( node, header ) );
+	}
+
+	// tests copied over from org.hibernate.test.hql.HqlParserTest ~~~~~~~~~~~~
+
+	public void testUnion() throws Exception {
+		parse("from Animal a where a in (from Cat union from Dog) ");
+	}
+
+	/**
+	 * Section 9.2 - from *
+	 */
+	public void testDocoExamples92() throws Exception {
+		parse( "from eg.Cat" );
+		parse( "from eg.Cat as cat" );
+		parse( "from eg.Cat cat" );
+		parse( "from Formula, Parameter" );
+		parse( "from Formula as form, Parameter as param" );
+	}
+
+	/**
+	 * Section 9.3 - Associations and joins *
+	 */
+	public void testDocoExamples93() throws Exception {
+		parse( "from eg.Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten" );
+		parse( "from eg.Cat as cat left join cat.mate.kittens as kittens" );
+		parse( "from Formula form full join form.parameter param" );
+		parse( "from eg.Cat as cat join cat.mate as mate left join cat.kittens as kitten" );
+		parse( "from eg.Cat as cat\ninner join fetch cat.mate\nleft join fetch cat.kittens" );
+	}
+
+	/**
+	 * Section 9.4 - Select *
+	 */
+	public void testDocoExamples94() throws Exception {
+		parse( "select mate from eg.Cat as cat inner join cat.mate as mate" );
+		parse( "select cat.mate from eg.Cat cat" );
+		parse( "select elements(cat.kittens) from eg.Cat cat" );
+		parse( "select cat.name from eg.DomesticCat cat where cat.name like 'fri%'" );
+		parse( "select cust.name.firstName from Customer as cust" );
+		parse( "select mother, offspr, mate.name from eg.DomesticCat\n"
+				+ " as mother inner join mother.mate as mate left outer join\n"
+				+ "mother.kittens as offspr" );
+		parse( "select new Family(mother, mate, offspr)\n"
+				+ "from eg.DomesticCat as mother\n"
+				+ "join mother.mate as mate\n"
+				+ "left join mother.kittens as offspr\n" );
+	}
+
+	/**
+	 * Section 9.5 - Aggregate functions *
+	 */
+	public void testDocoExamples95() throws Exception {
+		parse( "select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)\n"
+				+ "from eg.Cat cat" );
+		parse( "select cat, count( elements(cat.kittens) )\n"
+				+ " from eg.Cat cat group by cat" );
+		parse( "select distinct cat.name from eg.Cat cat" );
+		parse( "select count(distinct cat.name), count(cat) from eg.Cat cat" );
+	}
+
+	/**
+	 * Section 9.6 - Polymorphism *
+	 */
+	public void testDocoExamples96() throws Exception {
+		parse( "from eg.Cat as cat" );
+		parse( "from java.lang.Object o" );
+		parse( "from eg.Named n, eg.Named m where n.name = m.name" );
+	}
+
+	/**
+	 * Section 9.7 - Where *
+	 */
+	public void testDocoExamples97() throws Exception {
+		parse( "from eg.Cat as cat where cat.name='Fritz'" );
+		parse( "select foo\n"
+				+ "from eg.Foo foo, eg.Bar bar\n"
+				+ "where foo.startDate = bar.date\n" );
+		parse( "from eg.Cat cat where cat.mate.name is not null" );
+		parse( "from eg.Cat cat, eg.Cat rival where cat.mate = rival.mate" );
+		parse( "select cat, mate\n"
+				+ "from eg.Cat cat, eg.Cat mate\n"
+				+ "where cat.mate = mate" );
+		parse( "from eg.Cat as cat where cat.id = 123" );
+		parse( "from eg.Cat as cat where cat.mate.id = 69" );
+		parse( "from bank.Person person\n"
+				+ "where person.id.country = 'AU'\n"
+				+ "and person.id.medicareNumber = 123456" );
+		parse( "from bank.Account account\n"
+				+ "where account.owner.id.country = 'AU'\n"
+				+ "and account.owner.id.medicareNumber = 123456" );
+		parse( "from eg.Cat cat where cat.class = eg.DomesticCat" );
+		parse( "from eg.AuditLog log, eg.Payment payment\n"
+				+ "where log.item.class = 'eg.Payment' and log.item.id = payment.id" );
+	}
+
+	/**
+	 * Section 9.8 - Expressions *
+	 */
+	public void testDocoExamples98() throws Exception {
+		parse( "from eg.DomesticCat cat where cat.name between 'A' and 'B'" );
+		parse( "from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )" );
+		parse( "from eg.DomesticCat cat where cat.name not between 'A' and 'B'" );
+		parse( "from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )" );
+		parse( "from eg.Cat cat where cat.kittens.size > 0" );
+		parse( "from eg.Cat cat where size(cat.kittens) > 0" );
+// This is a little odd.  I'm not sure whether 'current' is a keyword.
+//        parse("from Calendar cal where cal.holidays.maxElement > current date");
+// Using the token 'order' as both a keyword and an identifier works now, but
+// the second instance causes some problems because order is valid in the second instance.
+//        parse("from Order order where maxindex(order.items) > 100");
+//        parse("from Order order where minelement(order.items) > 10000");
+		parse( "from Order ord where maxindex(ord.items) > 100" );
+		parse( "from Order ord where minelement(ord.items) > 10000" );
+
+		parse( "select mother from eg.Cat as mother, eg.Cat as kit\n"
+				+ "where kit in elements(foo.kittens)" );
+		parse( "select p from eg.NameList list, eg.Person p\n"
+				+ "where p.name = some elements(list.names)" );
+		parse( "from eg.Cat cat where exists elements(cat.kittens)" );
+		parse( "from eg.Player p where 3 > all elements(p.scores)" );
+		parse( "from eg.Show show where 'fizard' in indices(show.acts)" );
+
+		// Yet another example of the pathological 'order' token.
+//        parse("from Order order where order.items[0].id = 1234");
+//        parse("select person from Person person, Calendar calendar\n"
+//        + "where calendar.holidays['national day'] = person.birthDay\n"
+//        + "and person.nationality.calendar = calendar");
+//        parse("select item from Item item, Order order\n"
+//        + "where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11");
+//        parse("select item from Item item, Order order\n"
+//        + "where order.items[ maxindex(order.items) ] = item and order.id = 11");
+
+		parse( "from Order ord where ord.items[0].id = 1234" );
+		parse( "select person from Person person, Calendar calendar\n"
+				+ "where calendar.holidays['national day'] = person.birthDay\n"
+				+ "and person.nationality.calendar = calendar" );
+		parse( "select item from Item item, Order ord\n"
+				+ "where ord.items[ ord.deliveredItemIndices[0] ] = item and ord.id = 11" );
+		parse( "select item from Item item, Order ord\n"
+				+ "where ord.items[ maxindex(ord.items) ] = item and ord.id = 11" );
+
+		parse( "select item from Item item, Order ord\n"
+				+ "where ord.items[ size(ord.items) - 1 ] = item" );
+
+		parse( "from eg.DomesticCat cat where upper(cat.name) like 'FRI%'" );
+
+		parse( "select cust from Product prod, Store store\n"
+				+ "inner join store.customers cust\n"
+				+ "where prod.name = 'widget'\n"
+				+ "and store.location.name in ( 'Melbourne', 'Sydney' )\n"
+				+ "and prod = all elements(cust.currentOrder.lineItems)" );
+
+	}
+
+	public void testDocoExamples99() throws Exception {
+		parse( "from eg.DomesticCat cat\n"
+				+ "order by cat.name asc, cat.weight desc, cat.birthdate" );
+	}
+
+	public void testDocoExamples910() throws Exception {
+		parse( "select cat.color, sum(cat.weight), count(cat)\n"
+				+ "from eg.Cat cat group by cat.color" );
+		parse( "select foo.id, avg( elements(foo.names) ), max( indices(foo.names) )\n"
+				+ "from eg.Foo foo group by foo.id" );
+		parse( "select cat.color, sum(cat.weight), count(cat)\n"
+				+ "from eg.Cat cat group by cat.color\n"
+				+ "having cat.color in (eg.Color.TABBY, eg.Color.BLACK)" );
+		parse( "select cat from eg.Cat cat join cat.kittens kitten\n"
+				+ "group by cat having avg(kitten.weight) > 100\n"
+				+ "order by count(kitten) asc, sum(kitten.weight) desc" );
+	}
+
+	public void testDocoExamples911() throws Exception {
+		parse( "from eg.Cat as fatcat where fatcat.weight > (\n"
+				+ "select avg(cat.weight) from eg.DomesticCat cat)" );
+		parse( "from eg.DomesticCat as cat where cat.name = some (\n"
+				+ "select name.nickName from eg.Name as name)\n" );
+		parse( "from eg.Cat as cat where not exists (\n"
+				+ "from eg.Cat as mate where mate.mate = cat)" );
+		parse( "from eg.DomesticCat as cat where cat.name not in (\n"
+				+ "select name.nickName from eg.Name as name)" );
+	}
+
+	public void testDocoExamples912() throws Exception {
+		parse( "select ord.id, sum(price.amount), count(item)\n"
+				+ "from Order as ord join ord.lineItems as item\n"
+				+ "join item.product as product, Catalog as catalog\n"
+				+ "join catalog.prices as price\n"
+				+ "where ord.paid = false\n"
+				+ "and ord.customer = :customer\n"
+				+ "and price.product = product\n"
+				+ "and catalog.effectiveDate < sysdate\n"
+				+ "and catalog.effectiveDate >= all (\n"
+				+ "select cat.effectiveDate from Catalog as cat where cat.effectiveDate < sysdate)\n"
+				+ "group by ord\n"
+				+ "having sum(price.amount) > :minAmount\n"
+				+ "order by sum(price.amount) desc" );
+
+		parse( "select ord.id, sum(price.amount), count(item)\n"
+				+ "from Order as ord join ord.lineItems as item join item.product as product,\n"
+				+ "Catalog as catalog join catalog.prices as price\n"
+				+ "where ord.paid = false and ord.customer = :customer\n"
+				+ "and price.product = product and catalog = :currentCatalog\n"
+				+ "group by ord having sum(price.amount) > :minAmount\n"
+				+ "order by sum(price.amount) desc" );
+
+		parse( "select count(payment), status.name \n"
+				+ "from Payment as payment \n"
+				+ "    join payment.currentStatus as status\n"
+				+ "    join payment.statusChanges as statusChange\n"
+				+ "where payment.status.name <> PaymentStatus.AWAITING_APPROVAL\n"
+				+ "    or (\n"
+				+ "        statusChange.timeStamp = ( \n"
+				+ "            select max(change.timeStamp) \n"
+				+ "            from PaymentStatusChange change \n"
+				+ "            where change.payment = payment\n"
+				+ "        )\n"
+				+ "        and statusChange.user <> :currentUser\n"
+				+ "    )\n"
+				+ "group by status.name, status.sortOrder\n"
+				+ "order by status.sortOrder" );
+		parse( "select count(payment), status.name \n"
+				+ "from Payment as payment\n"
+				+ "    join payment.currentStatus as status\n"
+				+ "where payment.status.name <> PaymentStatus.AWAITING_APPROVAL\n"
+				+ "    or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser\n"
+				+ "group by status.name, status.sortOrder\n"
+				+ "order by status.sortOrder" );
+		parse( "select account, payment\n"
+				+ "from Account as account\n"
+				+ "    left outer join account.payments as payment\n"
+				+ "where :currentUser in elements(account.holder.users)\n"
+				+ "    and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)\n"
+				+ "order by account.type.sortOrder, account.accountNumber, payment.dueDate" );
+		parse( "select account, payment\n"
+				+ "from Account as account\n"
+				+ "    join account.holder.users as user\n"
+				+ "    left outer join account.payments as payment\n"
+				+ "where :currentUser = user\n"
+				+ "    and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)\n"
+				+ "order by account.type.sortOrder, account.accountNumber, payment.dueDate" );
+	}
+
+	public void testExamples1() throws Exception {
+		parse( "select new org.hibernate.test.S(s.count, s.address)\n"
+				+ "from s in class Simple" );
+		parse( "select s.name, sysdate, trunc(s.pay), round(s.pay) from s in class Simple" );
+		parse( "select round(s.pay, 2) from s" );
+		parse( "select abs(round(s.pay)) from s in class Simple" );
+		parse( "select trunc(round(sysdate)) from s in class Simple" );
+	}
+
+	public void testArrayExpr() throws Exception {
+		parse( "from Order ord where ord.items[0].id = 1234" );
+	}
+
+	public void testMultipleActualParameters() throws Exception {
+		parse( "select round(s.pay, 2) from s" );
+	}
+
+	public void testMultipleFromClasses() throws Exception {
+		parse( "FROM eg.mypackage.Cat qat, com.toadstool.Foo f" );
+		parse( "FROM eg.mypackage.Cat qat, org.jabberwocky.Dipstick" );
+	}
+
+	public void testFromWithJoin() throws Exception {
+		parse( "FROM eg.mypackage.Cat qat, com.toadstool.Foo f join net.sf.blurb.Blurb" );
+		parse( "FROM eg.mypackage.Cat qat  left join com.multijoin.JoinORama , com.toadstool.Foo f join net.sf.blurb.Blurb" );
+	}
+
+	public void testSelect() throws Exception {
+		parse( "SELECT f FROM eg.mypackage.Cat qat, com.toadstool.Foo f join net.sf.blurb.Blurb" );
+		parse( "SELECT DISTINCT bar FROM eg.mypackage.Cat qat  left join com.multijoin.JoinORama as bar, com.toadstool.Foo f join net.sf.blurb.Blurb" );
+		parse( "SELECT count(*) FROM eg.mypackage.Cat qat" );
+		parse( "SELECT avg(qat.weight) FROM eg.mypackage.Cat qat" );
+	}
+
+	public void testWhere() throws Exception {
+		parse( "FROM eg.mypackage.Cat qat where qat.name like '%fluffy%' or qat.toes > 5" );
+		parse( "FROM eg.mypackage.Cat qat where not qat.name like '%fluffy%' or qat.toes > 5" );
+		parse( "FROM eg.mypackage.Cat qat where not qat.name not like '%fluffy%'" );
+		parse( "FROM eg.mypackage.Cat qat where qat.name in ('crater','bean','fluffy')" );
+		parse( "FROM eg.mypackage.Cat qat where qat.name not in ('crater','bean','fluffy')" );
+		parse( "from Animal an where sqrt(an.bodyWeight)/2 > 10" );
+		parse( "from Animal an where (an.bodyWeight > 10 and an.bodyWeight < 100) or an.bodyWeight is null" );
+	}
+
+	public void testGroupBy() throws Exception {
+		parse( "FROM eg.mypackage.Cat qat group by qat.breed" );
+		parse( "FROM eg.mypackage.Cat qat group by qat.breed, qat.eyecolor" );
+	}
+
+	public void testOrderBy() throws Exception {
+		parse( "FROM eg.mypackage.Cat qat order by avg(qat.toes)" );
+		parse( "from Animal an order by sqrt(an.bodyWeight)/2" );
+	}
+
+	public void testDoubleLiteral() throws Exception {
+		parse( "from eg.Cat as tinycat where fatcat.weight < 3.1415" );
+		parse( "from eg.Cat as enormouscat where fatcat.weight > 3.1415e3" );
+	}
+
+	public void testComplexConstructor() throws Exception {
+		parse( "select new Foo(count(bar)) from bar" );
+		parse( "select new Foo(count(bar),(select count(*) from doofus d where d.gob = 'fat' )) from bar" );
+	}
+
+
+	public void testInNotIn() throws Exception {
+		parse( "from foo where foo.bar in ('a' , 'b', 'c')" );
+		parse( "from foo where foo.bar not in ('a' , 'b', 'c')" );
+	}
+
+	public void testOperatorPrecedence() throws Exception {
+		parse( "from foo where foo.bar = 123 + foo.baz * foo.not" );
+		parse( "from foo where foo.bar like 'testzzz' || foo.baz or foo.bar in ('duh', 'gob')" );
+	}
+
+	/**
+	 * Tests HQL generated by the other unit tests.
+	 *
+	 * @throws Exception if the HQL could not be parsed.
+	 */
+	public void testUnitTestHql() throws Exception {
+		parse( "select foo from foo in class org.hibernate.test.Foo, fee in class org.hibernate.test.Fee where foo.dependent = fee order by foo.string desc, foo.component.count asc, fee.id" );
+		parse( "select foo.foo, foo.dependent from foo in class org.hibernate.test.Foo order by foo.foo.string desc, foo.component.count asc, foo.dependent.id" );
+		parse( "select foo from foo in class org.hibernate.test.Foo order by foo.dependent.id, foo.dependent.fi" );
+		parse( "SELECT one FROM one IN CLASS org.hibernate.test.One ORDER BY one.value ASC" );
+		parse( "SELECT many.one FROM many IN CLASS org.hibernate.test.Many ORDER BY many.one.value ASC, many.one.id" );
+		parse( "select foo.id from org.hibernate.test.Foo foo where foo.joinedProp = 'foo'" );
+		parse( "from org.hibernate.test.Foo foo inner join fetch foo.foo" );
+		parse( "from org.hibernate.test.Baz baz left outer join fetch baz.fooToGlarch" );
+		parse( "select foo.foo.foo.string from foo in class org.hibernate.test.Foo where foo.foo = 'bar'" );
+		parse( "select foo.foo.foo.foo.string from foo in class org.hibernate.test.Foo where foo.foo.foo = 'bar'" );
+		parse( "select foo.foo.foo.string from foo in class org.hibernate.test.Foo where foo.foo.foo.foo.string = 'bar'" );
+		parse( "select foo.string from foo in class org.hibernate.test.Foo where foo.foo.foo = 'bar' and foo.foo.foo.foo = 'baz'" );
+		parse( "select foo.string from foo in class org.hibernate.test.Foo where foo.foo.foo.foo.string = 'a' and foo.foo.string = 'b'" );
+		parse( "from org.hibernate.test.Foo as foo where foo.component.glarch.name is not null" );
+		parse( "from org.hibernate.test.Foo as foo left outer join foo.component.glarch as glarch where glarch.name = 'foo'" );
+		parse( "from org.hibernate.test.Foo" );
+		parse( "from org.hibernate.test.Foo foo left outer join foo.foo" );
+		parse( "from org.hibernate.test.Foo, org.hibernate.test.Bar" );
+		parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch, org.hibernate.test.Bar bar join bar.foo" );
+		parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch join baz.fooSet" );
+		parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch join fetch baz.fooSet foo left join fetch foo.foo" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.string='osama bin laden' and foo.boolean = true order by foo.string asc, foo.component.count desc" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.string='osama bin laden' order by foo.string asc, foo.component.count desc" );
+		parse( "select foo.foo from foo in class org.hibernate.test.Foo" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.component.count is null order by foo.component.count" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.component.name='foo'" );
+		parse( "select distinct foo.component.name, foo.component.name from foo in class org.hibernate.test.Foo where foo.component.name='foo'" );
+		parse( "select distinct foo.component.name, foo.id from foo in class org.hibernate.test.Foo where foo.component.name='foo'" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.id=?" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.key=?" );
+		parse( "select foo.foo from foo in class org.hibernate.test.Foo where foo.string='fizard'" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.component.subcomponent.name='bar'" );
+		parse( "select foo.foo from foo in class org.hibernate.test.Foo where foo.foo.id=?" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.foo = ?" );
+		parse( "from bar in class org.hibernate.test.Bar where bar.string='a string' or bar.string='a string'" );
+		parse( "select foo.component.name, elements(foo.component.importantDates) from foo in class org.hibernate.test.Foo where foo.foo.id=?" );
+		parse( "select max(elements(foo.component.importantDates)) from foo in class org.hibernate.test.Foo group by foo.id" );
+		parse( "select foo.foo.foo.foo from foo in class org.hibernate.test.Foo, foo2 in class org.hibernate.test.Foo where foo = foo2.foo and not not ( not foo.string='fizard' ) and foo2.string between 'a' and (foo.foo.string) and ( foo2.string in ( 'fiz', 'blah') or 1=1 )" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.string='from BoogieDown  -tinsel town  =!@#$^&*())'" );
+		parse( "from foo in class org.hibernate.test.Foo where not foo.string='foo''bar'" ); // Added quote quote is an escape
+		parse( "from foo in class org.hibernate.test.Foo where foo.component.glarch.next is null" );
+		parse( " from bar in class org.hibernate.test.Bar where bar.baz.count=667 and bar.baz.count!=123 and not bar.baz.name='1-E-1'" );
+		parse( " from i in class org.hibernate.test.Bar where i.baz.name='Bazza'" );
+		parse( "select count(distinct foo.foo) from foo in class org.hibernate.test.Foo" );
+		parse( "select count(foo.foo.boolean) from foo in class org.hibernate.test.Foo" );
+		parse( "select count(*), foo.int from foo in class org.hibernate.test.Foo group by foo.int" );
+		parse( "select sum(foo.foo.int) from foo in class org.hibernate.test.Foo" );
+		parse( "select count(foo) from foo in class org.hibernate.test.Foo where foo.id=?" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.boolean = ?" );
+		parse( "select new Foo(fo.x) from org.hibernate.test.Fo fo" );
+		parse( "select new Foo(fo.integer) from org.hibernate.test.Foo fo" );
+		parse( "select new Foo(fo.x) from org.hibernate.test.Foo fo" );
+		parse( "select foo.long, foo.component.name, foo, foo.foo from foo in class org.hibernate.test.Foo" );
+		parse( "select avg(foo.float), max(foo.component.name), count(distinct foo.id) from foo in class org.hibernate.test.Foo" );
+		parse( "select foo.long, foo.component, foo, foo.foo from foo in class org.hibernate.test.Foo" );
+		parse( "from o in class org.hibernate.test.MoreStuff" );
+		parse( "from o in class org.hibernate.test.Many" );
+		parse( "from o in class org.hibernate.test.Fee" );
+		parse( "from o in class org.hibernate.test.Qux" );
+		parse( "from o in class org.hibernate.test.Y" );
+		parse( "from o in class org.hibernate.test.Fumm" );
+		parse( "from o in class org.hibernate.test.X" );
+		parse( "from o in class org.hibernate.test.Simple" );
+		parse( "from o in class org.hibernate.test.Location" );
+		parse( "from o in class org.hibernate.test.Holder" );
+		parse( "from o in class org.hibernate.test.Part" );
+		parse( "from o in class org.hibernate.test.Baz" );
+		parse( "from o in class org.hibernate.test.Vetoer" );
+		parse( "from o in class org.hibernate.test.Sortable" );
+		parse( "from o in class org.hibernate.test.Contained" );
+		parse( "from o in class org.hibernate.test.Stuff" );
+		parse( "from o in class org.hibernate.test.Immutable" );
+		parse( "from o in class org.hibernate.test.Container" );
+		parse( "from o in class org.hibernate.test.X$XX" );
+		parse( "from o in class org.hibernate.test.One" );
+		parse( "from o in class org.hibernate.test.Foo" );
+		parse( "from o in class org.hibernate.test.Fo" );
+		parse( "from o in class org.hibernate.test.Glarch" );
+		parse( "from o in class org.hibernate.test.Fum" );
+		parse( "from n in class org.hibernate.test.Holder" );
+		parse( "from n in class org.hibernate.test.Baz" );
+		parse( "from n in class org.hibernate.test.Bar" );
+		parse( "from n in class org.hibernate.test.Glarch" );
+		parse( "from n in class org.hibernate.test.Holder where n.name is not null" );
+		parse( "from n in class org.hibernate.test.Baz where n.name is not null" );
+		parse( "from n in class org.hibernate.test.Bar where n.name is not null" );
+		parse( "from n in class org.hibernate.test.Glarch where n.name is not null" );
+		parse( "from n in class org.hibernate.test.Holder" );
+		parse( "from n in class org.hibernate.test.Baz" );
+		parse( "from n in class org.hibernate.test.Bar" );
+		parse( "from n in class org.hibernate.test.Glarch" );
+		parse( "from n0 in class org.hibernate.test.Holder, n1 in class org.hibernate.test.Holder where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Baz, n1 in class org.hibernate.test.Holder where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Bar, n1 in class org.hibernate.test.Holder where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Glarch, n1 in class org.hibernate.test.Holder where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Holder, n1 in class org.hibernate.test.Baz where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Baz, n1 in class org.hibernate.test.Baz where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Bar, n1 in class org.hibernate.test.Baz where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Glarch, n1 in class org.hibernate.test.Baz where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Holder, n1 in class org.hibernate.test.Bar where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Baz, n1 in class org.hibernate.test.Bar where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Bar, n1 in class org.hibernate.test.Bar where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Glarch, n1 in class org.hibernate.test.Bar where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Holder, n1 in class org.hibernate.test.Glarch where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Baz, n1 in class org.hibernate.test.Glarch where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Bar, n1 in class org.hibernate.test.Glarch where n0.name = n1.name" );
+		parse( "from n0 in class org.hibernate.test.Glarch, n1 in class org.hibernate.test.Glarch where n0.name = n1.name" );
+		parse( "from n in class org.hibernate.test.Holder where n.name = :name" );
+		parse( "from o in class org.hibernate.test.MoreStuff" );
+		parse( "from o in class org.hibernate.test.Many" );
+		parse( "from o in class org.hibernate.test.Fee" );
+		parse( "from o in class org.hibernate.test.Qux" );
+		parse( "from o in class org.hibernate.test.Y" );
+		parse( "from o in class org.hibernate.test.Fumm" );
+		parse( "from o in class org.hibernate.test.X" );
+		parse( "from o in class org.hibernate.test.Simple" );
+		parse( "from o in class org.hibernate.test.Location" );
+		parse( "from o in class org.hibernate.test.Holder" );
+		parse( "from o in class org.hibernate.test.Part" );
+		parse( "from o in class org.hibernate.test.Baz" );
+		parse( "from o in class org.hibernate.test.Vetoer" );
+		parse( "from o in class org.hibernate.test.Sortable" );
+		parse( "from o in class org.hibernate.test.Contained" );
+		parse( "from o in class org.hibernate.test.Stuff" );
+		parse( "from o in class org.hibernate.test.Immutable" );
+		parse( "from o in class org.hibernate.test.Container" );
+		parse( "from o in class org.hibernate.test.X$XX" );
+		parse( "from o in class org.hibernate.test.One" );
+		parse( "from o in class org.hibernate.test.Foo" );
+		parse( "from o in class org.hibernate.test.Fo" );
+		parse( "from o in class org.hibernate.test.Glarch" );
+		parse( "from o in class org.hibernate.test.Fum" );
+		parse( "select baz.code, min(baz.count) from baz in class org.hibernate.test.Baz group by baz.code" );
+		parse( "selecT baz from baz in class org.hibernate.test.Baz where baz.stringDateMap['foo'] is not null or baz.stringDateMap['bar'] = ?" );
+		parse( "select baz from baz in class org.hibernate.test.Baz where baz.stringDateMap['now'] is not null" );
+		parse( "select baz from baz in class org.hibernate.test.Baz where baz.stringDateMap['now'] is not null and baz.stringDateMap['big bang'] < baz.stringDateMap['now']" );
+		parse( "select index(date) from org.hibernate.test.Baz baz join baz.stringDateMap as date" );
+		parse( "select index(date) from org.hibernate.test.Baz baz join baz.stringDateMap date" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.integer not between 1 and 5 and foo.string not in ('cde', 'abc') and foo.string is not null and foo.integer<=3" );
+		parse( "from org.hibernate.test.Baz baz inner join baz.collectionComponent.nested.foos foo where foo.string is null" );
+		parse( "from org.hibernate.test.Baz baz inner join baz.fooSet where '1' in (from baz.fooSet foo where foo.string is not null)" );
+		parse( "from org.hibernate.test.Baz baz where 'a' in elements(baz.collectionComponent.nested.foos) and 1.0 in elements(baz.collectionComponent.nested.floats)" );
+		parse( "from org.hibernate.test.Foo foo join foo.foo where foo.foo in ('1','2','3')" );
+		parse( "select foo.foo from org.hibernate.test.Foo foo where foo.foo in ('1','2','3')" );
+		parse( "select foo.foo.string from org.hibernate.test.Foo foo where foo.foo in ('1','2','3')" );
+		parse( "select foo.foo.string from org.hibernate.test.Foo foo where foo.foo.string in ('1','2','3')" );
+		parse( "select foo.foo.long from org.hibernate.test.Foo foo where foo.foo.string in ('1','2','3')" );
+		parse( "select count(*) from org.hibernate.test.Foo foo where foo.foo.string in ('1','2','3') or foo.foo.long in (1,2,3)" );
+		parse( "select count(*) from org.hibernate.test.Foo foo where foo.foo.string in ('1','2','3') group by foo.foo.long" );
+		parse( "from org.hibernate.test.Foo foo1 left join foo1.foo foo2 left join foo2.foo where foo1.string is not null" );
+		parse( "from org.hibernate.test.Foo foo1 left join foo1.foo.foo where foo1.string is not null" );
+		parse( "from org.hibernate.test.Foo foo1 left join foo1.foo foo2 left join foo1.foo.foo foo3 where foo1.string is not null" );
+		parse( "select foo.formula from org.hibernate.test.Foo foo where foo.formula > 0" );
+		parse( "from org.hibernate.test.Foo as foo join foo.foo as foo2 where foo2.id >'a' or foo2.id <'a'" );
+		parse( "from org.hibernate.test.Holder" );
+		parse( "from org.hibernate.test.Baz baz left outer join fetch baz.manyToAny" );
+		parse( "from org.hibernate.test.Baz baz join baz.manyToAny" );
+		parse( "select baz from org.hibernate.test.Baz baz join baz.manyToAny a where index(a) = 0" );
+		parse( "select bar from org.hibernate.test.Bar bar where bar.baz.stringDateMap['now'] is not null" );
+		parse( "select bar from org.hibernate.test.Bar bar join bar.baaz b where b.stringDateMap['big bang'] < b.stringDateMap['now'] and b.stringDateMap['now'] is not null" );
+		parse( "select bar from org.hibernate.test.Bar bar where bar.baz.stringDateMap['big bang'] < bar.baz.stringDateMap['now'] and bar.baz.stringDateMap['now'] is not null" );
+		parse( "select foo.string, foo.component, foo.id from org.hibernate.test.Bar foo" );
+		parse( "select elements(baz.components) from org.hibernate.test.Baz baz" );
+		parse( "select bc.name from org.hibernate.test.Baz baz join baz.components bc" );
+		parse( "from org.hibernate.test.Foo foo where foo.integer < 10 order by foo.string" );
+		parse( "from org.hibernate.test.Fee" );
+		parse( "from org.hibernate.test.Holder h join h.otherHolder oh where h.otherHolder.name = 'bar'" );
+		parse( "from org.hibernate.test.Baz baz join baz.fooSet foo join foo.foo.foo foo2 where foo2.string = 'foo'" );
+		parse( "from org.hibernate.test.Baz baz join baz.fooArray foo join foo.foo.foo foo2 where foo2.string = 'foo'" );
+		parse( "from org.hibernate.test.Baz baz join baz.stringDateMap date where index(date) = 'foo'" );
+		parse( "from org.hibernate.test.Baz baz join baz.topGlarchez g where index(g) = 'A'" );
+		parse( "select index(g) from org.hibernate.test.Baz baz join baz.topGlarchez g" );
+		parse( "from org.hibernate.test.Baz baz left join baz.stringSet" );
+		parse( "from org.hibernate.test.Baz baz join baz.stringSet str where str='foo'" );
+		parse( "from org.hibernate.test.Baz baz left join fetch baz.stringSet" );
+		parse( "from org.hibernate.test.Baz baz join baz.stringSet string where string='foo'" );
+		parse( "from org.hibernate.test.Baz baz inner join baz.components comp where comp.name='foo'" );
+		parse( "from org.hibernate.test.Glarch g inner join g.fooComponents comp where comp.fee is not null" );
+		parse( "from org.hibernate.test.Glarch g inner join g.fooComponents comp join comp.fee fee where fee.count > 0" );
+		parse( "from org.hibernate.test.Glarch g inner join g.fooComponents comp where comp.fee.count is not null" );
+		parse( "from org.hibernate.test.Baz baz left join fetch baz.fooBag" );
+		parse( "from org.hibernate.test.Glarch" );
+		parse( "from org.hibernate.test.Fee" );
+		parse( "from org.hibernate.test.Baz baz left join fetch baz.sortablez order by baz.name asc" );
+		parse( "from org.hibernate.test.Baz baz order by baz.name asc" );
+		parse( "from org.hibernate.test.Foo foo, org.hibernate.test.Baz baz left join fetch baz.fees" );
+		parse( "from org.hibernate.test.Foo foo, org.hibernate.test.Bar bar" );
+		parse( "from org.hibernate.test.Foo foo" );
+		parse( "from org.hibernate.test.Foo foo, org.hibernate.test.Bar bar, org.hibernate.test.Bar bar2" );
+		parse( "from org.hibernate.test.X x" );
+		parse( "from org.hibernate.test.Foo foo" );
+		parse( "select distinct foo from org.hibernate.test.Foo foo" );
+		parse( "from org.hibernate.test.Glarch g where g.multiple.glarch=g and g.multiple.count=12" );
+		parse( "from org.hibernate.test.Bar bar left join bar.baz baz left join baz.cascadingBars b where bar.name like 'Bar %'" );
+		parse( "select bar, b from org.hibernate.test.Bar bar left join bar.baz baz left join baz.cascadingBars b where bar.name like 'Bar%'" );
+		parse( "select bar, b from org.hibernate.test.Bar bar left join bar.baz baz left join baz.cascadingBars b where ( bar.name in (:nameList0_, :nameList1_, :nameList2_) or bar.name in (:nameList0_, :nameList1_, :nameList2_) ) and bar.string = :stringVal" );
+		parse( "select bar, b from org.hibernate.test.Bar bar inner join bar.baz baz inner join baz.cascadingBars b where bar.name like 'Bar%'" );
+		parse( "select bar, b from org.hibernate.test.Bar bar left join bar.baz baz left join baz.cascadingBars b where bar.name like :name and b.name like :name" );
+		parse( "select bar from org.hibernate.test.Bar as bar where bar.x > ? or bar.short = 1 or bar.string = 'ff ? bb'" );
+		parse( "select bar from org.hibernate.test.Bar as bar where bar.string = ' ? ' or bar.string = '?'" );
+		parse( "from org.hibernate.test.Baz baz, baz.fooArray foo" );
+		parse( "from s in class org.hibernate.test.Stuff where s.foo.id = ? and s.id.id = ? and s.moreStuff.id.intId = ? and s.moreStuff.id.stringId = ?" );
+		parse( "from s in class org.hibernate.test.Stuff where s.foo.id = ? and s.id.id = ? and s.moreStuff.name = ?" );
+		parse( "from s in class org.hibernate.test.Stuff where s.foo.string is not null" );
+		parse( "from s in class org.hibernate.test.Stuff where s.foo > '0' order by s.foo" );
+		parse( "from ms in class org.hibernate.test.MoreStuff" );
+		parse( "from foo in class org.hibernate.test.Foo" );
+		parse( "from fee in class org.hibernate.test.Fee" );
+		parse( "select new Result(foo.string, foo.long, foo.integer) from foo in class org.hibernate.test.Foo" );
+		parse( "select new Result( baz.name, foo.long, count(elements(baz.fooArray)) ) from org.hibernate.test.Baz baz join baz.fooArray foo group by baz.name, foo.long" );
+		parse( "select new Result( baz.name, max(foo.long), count(foo) ) from org.hibernate.test.Baz baz join baz.fooArray foo group by baz.name" );
+		parse( "select max( elements(bar.baz.fooArray) ) from org.hibernate.test.Bar as bar" );
+		parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch join fetch baz.fooArray foo left join fetch foo.foo" );
+		parse( "select baz.name from org.hibernate.test.Bar bar inner join bar.baz baz inner join baz.fooSet foo where baz.name = bar.string" );
+		parse( "SELECT baz.name FROM org.hibernate.test.Bar AS bar INNER JOIN bar.baz AS baz INNER JOIN baz.fooSet AS foo WHERE baz.name = bar.string" );
+		parse( "select baz.name from org.hibernate.test.Bar bar join bar.baz baz left outer join baz.fooSet foo where baz.name = bar.string" );
+		parse( "select baz.name from org.hibernate.test.Bar bar, bar.baz baz, baz.fooSet foo where baz.name = bar.string" );
+		parse( "SELECT baz.name FROM org.hibernate.test.Bar AS bar, bar.baz AS baz, baz.fooSet AS foo WHERE baz.name = bar.string" );
+		parse( "select baz.name from org.hibernate.test.Bar bar left join bar.baz baz left join baz.fooSet foo where baz.name = bar.string" );
+		parse( "select foo.string from org.hibernate.test.Bar bar left join bar.baz.fooSet foo where bar.string = foo.string" );
+		parse( "select baz.name from org.hibernate.test.Bar bar left join bar.baz baz left join baz.fooArray foo where baz.name = bar.string" );
+		parse( "select foo.string from org.hibernate.test.Bar bar left join bar.baz.fooArray foo where bar.string = foo.string" );
+		parse( "select foo from bar in class org.hibernate.test.Bar inner join bar.baz as baz inner join baz.fooSet as foo" );
+		parse( "select foo from bar in class org.hibernate.test.Bar inner join bar.baz.fooSet as foo" );
+		parse( "select foo from bar in class org.hibernate.test.Bar, bar.baz as baz, baz.fooSet as foo" );
+		parse( "select foo from bar in class org.hibernate.test.Bar, bar.baz.fooSet as foo" );
+		parse( "from org.hibernate.test.Bar bar join bar.baz.fooArray foo" );
+		parse( "from bar in class org.hibernate.test.Bar, foo in elements( bar.baz.fooArray )" );
+		parse( "select one.id, elements(one.manies) from one in class org.hibernate.test.One" );
+		parse( "select max( elements(one.manies) ) from one in class org.hibernate.test.One" );
+		parse( "select one, elements(one.manies) from one in class org.hibernate.test.One" );
+		parse( "select one, max(elements(one.manies)) from one in class org.hibernate.test.One group by one" );
+		parse( "select elements(baz.fooArray) from baz in class org.hibernate.test.Baz where baz.id=?" );
+		parse( "select elements(baz.fooArray) from baz in class org.hibernate.test.Baz where baz.id=?" );
+		parse( "select indices(baz.fooArray) from baz in class org.hibernate.test.Baz where baz.id=?" );
+		parse( "select baz, max(elements(baz.timeArray)) from baz in class org.hibernate.test.Baz group by baz" );
+		parse( "select baz, baz.stringSet.size, count(distinct elements(baz.stringSet)), max(elements(baz.stringSet)) from baz in class org.hibernate.test.Baz group by baz" );
+		parse( "select max( elements(baz.timeArray) ) from baz in class org.hibernate.test.Baz where baz.id=?" );
+		parse( "select max(elements(baz.stringSet)) from baz in class org.hibernate.test.Baz where baz.id=?" );
+		parse( "select size(baz.stringSet) from baz in class org.hibernate.test.Baz where baz.id=?" );
+		parse( "from org.hibernate.test.Foo foo where foo.component.glarch.id is not null" );
+		parse( "from baz in class org.hibernate.test.Baz" );
+		parse( "select elements(baz.stringArray) from baz in class org.hibernate.test.Baz" );
+		parse( "from foo in class org.hibernate.test.Foo" );
+		parse( "select elements(baz.stringList) from baz in class org.hibernate.test.Baz" );
+		parse( "select count(*) from org.hibernate.test.Bar" );
+		parse( "select count(*) from b in class org.hibernate.test.Bar" );
+		parse( "from g in class org.hibernate.test.Glarch" );
+		parse( "select baz, baz from baz in class org.hibernate.test.Baz" );
+		parse( "select baz from baz in class org.hibernate.test.Baz order by baz" );
+		parse( "from bar in class org.hibernate.test.Bar" );
+		parse( "from g in class org.hibernate.test.Glarch" );
+		parse( "from f in class org.hibernate.test.Foo" );
+		parse( "from o in class org.hibernate.test.One" );
+		parse( "from q in class org.hibernate.test.Qux" );
+		parse( "select foo from foo in class org.hibernate.test.Foo where foo.string='foo bar'" );
+		parse( "from foo in class org.hibernate.test.Foo order by foo.string, foo.date" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.class='B'" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.class=Bar" );
+		parse( "select bar from bar in class org.hibernate.test.Bar, foo in class org.hibernate.test.Foo where bar.string = foo.string and not bar=foo" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.string='foo bar'" );
+		parse( "select foo from foo in class org.hibernate.test.Foo" );
+		parse( "from bar in class org.hibernate.test.Bar where bar.barString='bar bar'" );
+		parse( "from t in class org.hibernate.test.Trivial" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.date = ?" );
+		parse( "from o in class org.hibernate.test.MoreStuff" );
+		parse( "from o in class org.hibernate.test.Many" );
+		parse( "from o in class org.hibernate.test.Fee" );
+		parse( "from o in class org.hibernate.test.Qux" );
+		parse( "from o in class org.hibernate.test.Y" );
+		parse( "from o in class org.hibernate.test.Fumm" );
+		parse( "from o in class org.hibernate.test.X" );
+		parse( "from o in class org.hibernate.test.Simple" );
+		parse( "from o in class org.hibernate.test.Location" );
+		parse( "from o in class org.hibernate.test.Holder" );
+		parse( "from o in class org.hibernate.test.Part" );
+		parse( "from o in class org.hibernate.test.Baz" );
+		parse( "from o in class org.hibernate.test.Vetoer" );
+		parse( "from o in class org.hibernate.test.Sortable" );
+		parse( "from o in class org.hibernate.test.Contained" );
+		parse( "from o in class org.hibernate.test.Stuff" );
+		parse( "from o in class org.hibernate.test.Immutable" );
+		parse( "from o in class org.hibernate.test.Container" );
+		parse( "from o in class org.hibernate.test.X$XX" );
+		parse( "from o in class org.hibernate.test.One" );
+		parse( "from o in class org.hibernate.test.Foo" );
+		parse( "from o in class org.hibernate.test.Fo" );
+		parse( "from o in class org.hibernate.test.Glarch" );
+		parse( "from o in class org.hibernate.test.Fum" );
+		parse( "from q in class org.hibernate.test.Qux where q.stuff is null" );
+		parse( "from q in class org.hibernate.test.Qux where q.stuff=?" );
+		parse( "from q in class org.hibernate.test.Qux" );
+		parse( "from g in class org.hibernate.test.Glarch where g.version=2" );
+		parse( "from g in class org.hibernate.test.Glarch where g.next is not null" );
+		parse( "from g in class org.hibernate.test.Glarch order by g.order asc" );
+		parse( "from foo in class org.hibernate.test.Foo order by foo.string asc" );
+		parse( "select parent, child from parent in class org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo = child" );
+		parse( "select count(distinct child.id), count(distinct parent.id) from parent in class org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo = child" );
+		parse( "select child.id, parent.id, child.long from parent in class org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo = child" );
+		parse( "select child.id, parent.id, child.long, child, parent.foo from parent in class org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo = child" );
+		parse( "select parent, child from parent in class org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo = child and parent.string='a string'" );
+		parse( "from fee in class org.hibernate.test.Fee" );
+		parse( "from org.hibernate.test.Foo foo where foo.custom.s1 = 'one'" );
+		parse( "from im in class org.hibernate.test.Immutable where im = ?" );
+		parse( "from foo in class org.hibernate.test.Foo" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.char='X'" );
+		parse( "select elements(baz.stringArray) from baz in class org.hibernate.test.Baz" );
+		parse( "select distinct elements(baz.stringArray) from baz in class org.hibernate.test.Baz" );
+		parse( "select elements(baz.fooArray) from baz in class org.hibernate.test.Baz" );
+		parse( "from foo in class org.hibernate.test.Fo" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.dependent.qux.foo.string = 'foo2'" );
+		parse( "from org.hibernate.test.Bar bar where bar.object.id = ? and bar.object.class = ?" );
+		parse( "select one from org.hibernate.test.One one, org.hibernate.test.Bar bar where bar.object.id = one.id and bar.object.class = 'O'" );
+		parse( "from l in class org.hibernate.test.Location where l.countryCode = 'AU' and l.description='foo bar'" );
+		parse( "from org.hibernate.test.Bar bar" );
+		parse( "From org.hibernate.test.Bar bar" );
+		parse( "From org.hibernate.test.Foo foo" );
+		parse( "from o in class org.hibernate.test.Baz" );
+		parse( "from o in class org.hibernate.test.Foo" );
+		parse( "from f in class org.hibernate.test.Foo" );
+		parse( "select fum.id from fum in class org.hibernate.test.Fum where not fum.fum='FRIEND'" );
+		parse( "select fum.id from fum in class org.hibernate.test.Fum where not fum.fum='FRIEND'" );
+		parse( "from fum in class org.hibernate.test.Fum where not fum.fum='FRIEND'" );
+		parse( "from fo in class org.hibernate.test.Fo where fo.id.string like 'an instance of fo'" );
+		parse( "from org.hibernate.test.Inner" );
+		parse( "from org.hibernate.test.Outer o where o.id.detailId = ?" );
+		parse( "from org.hibernate.test.Outer o where o.id.master.id.sup.dudu is not null" );
+		parse( "from org.hibernate.test.Outer o where o.id.master.id.sup.id.akey is not null" );
+		parse( "select o.id.master.id.sup.dudu from org.hibernate.test.Outer o where o.id.master.id.sup.dudu is not null" );
+		parse( "select o.id.master.id.sup.id.akey from org.hibernate.test.Outer o where o.id.master.id.sup.id.akey is not null" );
+		parse( "from org.hibernate.test.Outer o where o.id.master.bla = ''" );
+		parse( "from org.hibernate.test.Outer o where o.id.master.id.one = ''" );
+		parse( "from org.hibernate.test.Inner inn where inn.id.bkey is not null and inn.backOut.id.master.id.sup.id.akey > 'a'" );
+		parse( "from org.hibernate.test.Outer as o left join o.id.master m left join m.id.sup where o.bubu is not null" );
+		parse( "from org.hibernate.test.Outer as o left join o.id.master.id.sup s where o.bubu is not null" );
+		parse( "from org.hibernate.test.Outer as o left join o.id.master m left join o.id.master.id.sup s where o.bubu is not null" );
+		parse( "select fum1.fo from fum1 in class org.hibernate.test.Fum where fum1.fo.fum is not null" );
+		parse( "from fum1 in class org.hibernate.test.Fum where fum1.fo.fum is not null order by fum1.fo.fum" );
+		parse( "select elements(fum1.friends) from fum1 in class org.hibernate.test.Fum" );
+		parse( "from fum1 in class org.hibernate.test.Fum, fr in elements( fum1.friends )" );
+		parse( "select new Jay(eye) from org.hibernate.test.Eye eye" );
+		parse( "from org.hibernate.test.Category cat where cat.name='new foo'" );
+		parse( "from org.hibernate.test.Category cat where cat.name='new sub'" );
+		parse( "from org.hibernate.test.Up up order by up.id2 asc" );
+		parse( "from org.hibernate.test.Down down" );
+		parse( "from org.hibernate.test.Up up" );
+		parse( "from m in class org.hibernate.test.Master" );
+		parse( "from s in class org.hibernate.test.Several" );
+		parse( "from s in class org.hibernate.test.Single" );
+		parse( "\n" +
+				"		from d in class \n" +
+				"			org.hibernate.test.Detail\n" +
+				"	" );
+		parse( "from c in class org.hibernate.test.Category where c.name = org.hibernate.test.Category.ROOT_CATEGORY" );
+		parse( "select c from c in class org.hibernate.test.Container, s in class org.hibernate.test.Simple where c.oneToMany[2] = s" );
+		parse( "select c from c in class org.hibernate.test.Container, s in class org.hibernate.test.Simple where c.manyToMany[2] = s" );
+		parse( "select c from c in class org.hibernate.test.Container, s in class org.hibernate.test.Simple where s = c.oneToMany[2]" );
+		parse( "select c from c in class org.hibernate.test.Container, s in class org.hibernate.test.Simple where s = c.manyToMany[2]" );
+		parse( "select c from c in class org.hibernate.test.Container where c.oneToMany[0].name = 's'" );
+		parse( "select c from c in class org.hibernate.test.Container where c.manyToMany[0].name = 's'" );
+		parse( "select c from c in class org.hibernate.test.Container where 's' = c.oneToMany[2 - 2].name" );
+		parse( "select c from c in class org.hibernate.test.Container where 's' = c.manyToMany[(3+1)/4-1].name" );
+		parse( "select c from c in class org.hibernate.test.Container where c.manyToMany[ maxindex(c.manyToMany) ].count = 2" );
+		parse( "select c from c in class org.hibernate.test.Container where c.oneToMany[ c.manyToMany[0].count ].name = 's'" );
+		parse( "select c from org.hibernate.test.Container c where c.manyToMany[ c.oneToMany[0].count ].name = 's'" );
+		parse( "select count(comp.name) from org.hibernate.test.Container c join c.components comp" );
+		parse( "from org.hibernate.test.Parent p left join fetch p.child" );
+		parse( "from org.hibernate.test.Parent p join p.child c where c.x > 0" );
+		parse( "from org.hibernate.test.Child c join c.parent p where p.x > 0" );
+		parse( "from org.hibernate.test.Child" );
+		parse( "from org.hibernate.test.MoreStuff" );
+		parse( "from org.hibernate.test.Many" );
+		parse( "from org.hibernate.test.Fee" );
+		parse( "from org.hibernate.test.Qux" );
+		parse( "from org.hibernate.test.Fumm" );
+		parse( "from org.hibernate.test.Parent" );
+		parse( "from org.hibernate.test.Simple" );
+		parse( "from org.hibernate.test.Holder" );
+		parse( "from org.hibernate.test.Part" );
+		parse( "from org.hibernate.test.Baz" );
+		parse( "from org.hibernate.test.Vetoer" );
+		parse( "from org.hibernate.test.Sortable" );
+		parse( "from org.hibernate.test.Contained" );
+		parse( "from org.hibernate.test.Circular" );
+		parse( "from org.hibernate.test.Stuff" );
+		parse( "from org.hibernate.test.Immutable" );
+		parse( "from org.hibernate.test.Container" );
+		parse( "from org.hibernate.test.One" );
+		parse( "from org.hibernate.test.Foo" );
+		parse( "from org.hibernate.test.Fo" );
+		parse( "from org.hibernate.test.Glarch" );
+		parse( "from org.hibernate.test.Fum" );
+		parse( "from org.hibernate.test.Glarch g" );
+		parse( "from org.hibernate.test.Part" );
+		parse( "from org.hibernate.test.Baz baz join baz.parts" );
+		parse( "from c in class org.hibernate.test.Child where c.parent.count=66" );
+		parse( "from org.hibernate.test.Parent p join p.child c where p.count=66" );
+		parse( "select c, c.parent from c in class org.hibernate.test.Child order by c.parent.count" );
+		parse( "select c, c.parent from c in class org.hibernate.test.Child where c.parent.count=66 order by c.parent.count" );
+		parse( "select c, c.parent, c.parent.count from c in class org.hibernate.test.Child order by c.parent.count" );
+		parse( "FROM p IN CLASS org.hibernate.test.Parent WHERE p.count = ?" );
+		parse( "select count(*) from org.hibernate.test.Container as c join c.components as ce join ce.simple as s where ce.name='foo'" );
+		parse( "select c, s from org.hibernate.test.Container as c join c.components as ce join ce.simple as s where ce.name='foo'" );
+		parse( "from s in class org.hibernate.test.Simple" );
+		parse( "from m in class org.hibernate.test.Many" );
+		parse( "from o in class org.hibernate.test.One" );
+		parse( "from c in class org.hibernate.test.Container" );
+		parse( "from o in class org.hibernate.test.Child" );
+		parse( "from o in class org.hibernate.test.MoreStuff" );
+		parse( "from o in class org.hibernate.test.Many" );
+		parse( "from o in class org.hibernate.test.Fee" );
+		parse( "from o in class org.hibernate.test.Qux" );
+		parse( "from o in class org.hibernate.test.Fumm" );
+		parse( "from o in class org.hibernate.test.Parent" );
+		parse( "from o in class org.hibernate.test.Simple" );
+		parse( "from o in class org.hibernate.test.Holder" );
+		parse( "from o in class org.hibernate.test.Part" );
+		parse( "from o in class org.hibernate.test.Baz" );
+		parse( "from o in class org.hibernate.test.Vetoer" );
+		parse( "from o in class org.hibernate.test.Sortable" );
+		parse( "from o in class org.hibernate.test.Contained" );
+		parse( "from o in class org.hibernate.test.Circular" );
+		parse( "from o in class org.hibernate.test.Stuff" );
+		parse( "from o in class org.hibernate.test.Immutable" );
+		parse( "from o in class org.hibernate.test.Container" );
+		parse( "from o in class org.hibernate.test.One" );
+		parse( "from o in class org.hibernate.test.Foo" );
+		parse( "from o in class org.hibernate.test.Fo" );
+		parse( "from o in class org.hibernate.test.Glarch" );
+		parse( "from o in class org.hibernate.test.Fum" );
+		parse( "from c in class org.hibernate.test.C2 where 1=1 or 1=1" );
+		parse( "from b in class org.hibernate.test.B" );
+		parse( "from a in class org.hibernate.test.A" );
+		parse( "from b in class org.hibernate.test.B" );
+		parse( "from org.hibernate.test.E e join e.reverse as b where b.count=1" );
+		parse( "from org.hibernate.test.E e join e.as as b where b.count=1" );
+		parse( "from org.hibernate.test.B" );
+		parse( "from org.hibernate.test.C1" );
+		parse( "from org.hibernate.test.C2" );
+		parse( "from org.hibernate.test.E e, org.hibernate.test.A a where e.reverse = a.forward and a = ?" );
+		parse( "from org.hibernate.test.E e join fetch e.reverse" );
+		parse( "from org.hibernate.test.E e" );
+		parse( "select max(s.count) from s in class org.hibernate.test.Simple" );
+		parse( "select new org.hibernate.test.S(s.count, s.address) from s in class org.hibernate.test.Simple" );
+		parse( "select max(s.count) from s in class org.hibernate.test.Simple" );
+		parse( "select count(*) from s in class org.hibernate.test.Simple" );
+		parse( "from s in class org.hibernate.test.Simple where s.name=:name and s.count=:count" );
+		parse( "from s in class org.hibernate.test.Simple where s.name in (:several0_, :several1_)" );
+		parse( "from s in class org.hibernate.test.Simple where s.name in (:stuff0_, :stuff1_)" );
+		parse( "from org.hibernate.test.Simple s where s.name=?" );
+		parse( "from org.hibernate.test.Simple s where s.name=:name" );
+		parse( "from s in class org.hibernate.test.Simple where upper( s.name ) ='SIMPLE 1'" );
+		parse( "from s in class org.hibernate.test.Simple where not( upper( s.name ) ='yada' or 1=2 or 'foo'='bar' or not('foo'='foo') or 'foo' like 'bar' )" );
+		parse( "from s in class org.hibernate.test.Simple where lower( s.name || ' foo' ) ='simple 1 foo'" );
+		parse( "from s in class org.hibernate.test.Simple where upper( s.other.name ) ='SIMPLE 2'" );
+		parse( "from s in class org.hibernate.test.Simple where not ( upper( s.other.name ) ='SIMPLE 2' )" );
+		parse( "select distinct s from s in class org.hibernate.test.Simple where ( ( s.other.count + 3 ) = (15*2)/2 and s.count = 69) or ( ( s.other.count + 2 ) / 7 ) = 2" );
+		parse( "select s from s in class org.hibernate.test.Simple where ( ( s.other.count + 3 ) = (15*2)/2 and s.count = 69) or ( ( s.other.count + 2 ) / 7 ) = 2 order by s.other.count" );
+		parse( "select sum(s.count) from s in class org.hibernate.test.Simple group by s.count having sum(s.count) > 10" );
+		parse( "select s.count from s in class org.hibernate.test.Simple group by s.count having s.count = 12" );
+		parse( "select s.id, s.count, count(t), max(t.date) from s in class org.hibernate.test.Simple, t in class org.hibernate.test.Simple where s.count = t.count group by s.id, s.count order by s.count" );
+		parse( "from s in class org.hibernate.test.Simple" );
+		parse( "from s in class org.hibernate.test.Simple where s.name = ?" );
+		parse( "from s in class org.hibernate.test.Simple where s.name = ? and upper(s.name) = ?" );
+		parse( "from s in class org.hibernate.test.Simple where s.name = :foo and upper(s.name) = :bar or s.count=:count or s.count=:count + 1" );
+		parse( "select s.id from s in class org.hibernate.test.Simple" );
+		parse( "select all s, s.other from s in class org.hibernate.test.Simple where s = :s" );
+		parse( "from s in class org.hibernate.test.Simple where s.name in (:name_list0_, :name_list1_) and s.count > :count" );
+		parse( "from org.hibernate.test.Simple s" );
+		parse( "from org.hibernate.test.Simple s" );
+		parse( "from org.hibernate.test.Assignable" );
+		parse( "from org.hibernate.test.Category" );
+		parse( "from org.hibernate.test.Simple" );
+		parse( "from org.hibernate.test.A" );
+		parse( "from foo in class org.hibernate.test.Foo where foo.string=?" );
+		parse( "from foo in class org.hibernate.test.Foo" );
+		parse( "from org.hibernate.test.Po po, org.hibernate.test.Lower low where low.mypo = po" );
+		parse( "from org.hibernate.test.Po po join po.set as sm where sm.amount > 0" );
+		parse( "from org.hibernate.test.Po po join po.top as low where low.foo = 'po'" );
+		parse( "from org.hibernate.test.SubMulti sm join sm.children smc where smc.name > 'a'" );
+		parse( "select s, ya from org.hibernate.test.Lower s join s.yetanother ya" );
+		parse( "from org.hibernate.test.Lower s1 join s1.bag s2" );
+		parse( "from org.hibernate.test.Lower s1 left join s1.bag s2" );
+		parse( "select s, a from org.hibernate.test.Lower s join s.another a" );
+		parse( "select s, a from org.hibernate.test.Lower s left join s.another a" );
+		parse( "from org.hibernate.test.Top s, org.hibernate.test.Lower ls" );
+		parse( "from org.hibernate.test.Lower ls join ls.set s where s.name > 'a'" );
+		parse( "from org.hibernate.test.Po po join po.list sm where sm.name > 'a'" );
+		parse( "from org.hibernate.test.Lower ls inner join ls.another s where s.name is not null" );
+		parse( "from org.hibernate.test.Lower ls where ls.other.another.name is not null" );
+		parse( "from org.hibernate.test.Multi m where m.derived like 'F%'" );
+		parse( "from org.hibernate.test.SubMulti m where m.derived like 'F%'" );
+		parse( "select s from org.hibernate.test.SubMulti as sm join sm.children as s where s.amount>-1 and s.name is null" );
+		parse( "select elements(sm.children) from org.hibernate.test.SubMulti as sm" );
+		parse( "select distinct sm from org.hibernate.test.SubMulti as sm join sm.children as s where s.amount>-1 and s.name is null" );
+		parse( "select distinct s from s in class org.hibernate.test.SubMulti where s.moreChildren[1].amount < 1.0" );
+		parse( "from s in class org.hibernate.test.TrivialClass where s.id = 2" );
+		parse( "select s.count from s in class org.hibernate.test.Top" );
+		parse( "from s in class org.hibernate.test.Lower where s.another.name='name'" );
+		parse( "from s in class org.hibernate.test.Lower where s.yetanother.name='name'" );
+		parse( "from s in class org.hibernate.test.Lower where s.yetanother.name='name' and s.yetanother.foo is null" );
+		parse( "from s in class org.hibernate.test.Top where s.count=1" );
+		parse( "select s.count from s in class org.hibernate.test.Top, ls in class org.hibernate.test.Lower where ls.another=s" );
+		parse( "select elements(ls.bag), elements(ls.set) from ls in class org.hibernate.test.Lower" );
+		parse( "from s in class org.hibernate.test.Lower" );
+		parse( "from s in class org.hibernate.test.Top" );
+		parse( "from sm in class org.hibernate.test.SubMulti" );
+		parse( "select\n" +
+				"\n" +
+				"s from s in class org.hibernate.test.Top where s.count>0" );
+		parse( "from m in class org.hibernate.test.Multi where m.count>0 and m.extraProp is not null" );
+		parse( "from m in class org.hibernate.test.Top where m.count>0 and m.name is not null" );
+		parse( "from m in class org.hibernate.test.Lower where m.other is not null" );
+		parse( "from m in class org.hibernate.test.Multi where m.other.id = 1" );
+		parse( "from m in class org.hibernate.test.SubMulti where m.amount > 0.0" );
+		parse( "from m in class org.hibernate.test.Multi" );
+		parse( "from m in class org.hibernate.test.Multi where m.class = SubMulti" );
+		parse( "from m in class org.hibernate.test.Top where m.class = Multi" );
+		parse( "from s in class org.hibernate.test.Top" );
+		parse( "from ls in class org.hibernate.test.Lower" );
+		parse( "from ls in class org.hibernate.test.Lower, s in elements(ls.bag) where s.id is not null" );
+		parse( "from ls in class org.hibernate.test.Lower, s in elements(ls.set) where s.id is not null" );
+		parse( "from o in class org.hibernate.test.Top" );
+		parse( "from o in class org.hibernate.test.Po" );
+		parse( "from ChildMap cm where cm.parent is not null" );
+		parse( "from ParentMap cm where cm.child is not null" );
+		parse( "from org.hibernate.test.Componentizable" );
+	}
+
+	public void testUnnamedParameter() throws Exception {
+		parse( "select foo, bar from org.hibernate.test.Foo foo left outer join foo.foo bar where foo = ?" ); // Added '?' as a valid expression.
+	}
+
+	public void testInElements() throws Exception {
+		parse( "from bar in class org.hibernate.test.Bar, foo in elements(bar.baz.fooArray)" );   // Added collectionExpr as a valid 'in' clause.
+//		parse( "from org.hibernate.test.Bar bar, foo in elements(bar.baz.fooArray)" );   // Added collectionExpr as a valid 'in' clause.
+	}
+
+	public void testDotElements() throws Exception {
+		parse( "select distinct foo from baz in class org.hibernate.test.Baz, foo in elements(baz.fooArray)" );
+		parse( "select foo from baz in class org.hibernate.test.Baz, foo in elements(baz.fooSet)" );
+		parse( "select foo from baz in class org.hibernate.test.Baz, foo in elements(baz.fooArray)" );
+		parse( "from org.hibernate.test.Baz baz where 'b' in elements(baz.collectionComponent.nested.foos) and 1.0 in elements(baz.collectionComponent.nested.floats)" );
+	}
+
+	public void testSelectAll() throws Exception {
+		parse( "select all s, s.other from s in class org.hibernate.test.Simple where s = :s" );
+	}
+
+	public void testNot() throws Exception {
+		// Cover NOT optimization in HqlParser
+		parse( "from eg.Cat cat where not ( cat.kittens.size < 1 )" );
+		parse( "from eg.Cat cat where not ( cat.kittens.size > 1 )" );
+		parse( "from eg.Cat cat where not ( cat.kittens.size >= 1 )" );
+		parse( "from eg.Cat cat where not ( cat.kittens.size <= 1 )" );
+		parse( "from eg.DomesticCat cat where not ( cat.name between 'A' and 'B' ) " );
+		parse( "from eg.DomesticCat cat where not ( cat.name not between 'A' and 'B' ) " );
+		parse( "from eg.Cat cat where not ( not cat.kittens.size <= 1 )" );
+		parse( "from eg.Cat cat where not  not ( not cat.kittens.size <= 1 )" );
+	}
+
+	public void testOtherSyntax() throws Exception {
+		parse( "select bar from org.hibernate.test.Bar bar order by ((bar.x - :valueX)*(bar.x - :valueX))" );
+		parse( "from bar in class org.hibernate.test.Bar, foo in elements(bar.baz.fooSet)" );
+		parse( "from one in class org.hibernate.test.One, many in elements(one.manies) where one.id = 1 and many.id = 1" );
+		parse( "from org.hibernate.test.Inner _inner join _inner.middles middle" );
+		parse( "FROM m IN CLASS org.hibernate.test.Master WHERE NOT EXISTS ( FROM d IN elements(m.details) WHERE NOT d.i=5 )" );
+		parse( "FROM m IN CLASS org.hibernate.test.Master WHERE NOT 5 IN ( SELECT d.i FROM d IN elements(m.details) )" );
+		parse( "SELECT m FROM m IN CLASS org.hibernate.test.Master, d IN elements(m.details) WHERE d.i=5" );
+		parse( "SELECT m FROM m IN CLASS org.hibernate.test.Master, d IN elements(m.details) WHERE d.i=5" );
+		parse( "SELECT m.id FROM m IN CLASS org.hibernate.test.Master, d IN elements(m.details) WHERE d.i=5" );
+		// I'm not sure about these... [jsd]
+//        parse("select bar.string, foo.string from bar in class org.hibernate.test.Bar inner join bar.baz as baz inner join elements(baz.fooSet) as foo where baz.name = 'name'");
+//        parse("select bar.string, foo.string from bar in class org.hibernate.test.Bar, bar.baz as baz, elements(baz.fooSet) as foo where baz.name = 'name'");
+//        parse("select count(*) where this.amount>-1 and this.name is null");
+//        parse("from sm in class org.hibernate.test.SubMulti where exists sm.children.elements");
+	}
+
+	public void testEjbqlExtensions() throws Exception {
+		parse( "select object(a) from Animal a where a.mother member of a.offspring" );
+		parse( "select object(a) from Animal a where a.offspring is empty" );
+	}
+
+	public void testEmptyFilter() throws Exception {
+		parseFilter( "" );  //  Blank is a legitimate filter.
+	}
+
+	public void testOrderByFilter() throws Exception {
+		parseFilter( "order by this.id" );
+	}
+
+	public void testRestrictionFilter() throws Exception {
+		parseFilter( "where this.name = ?" );
+	}
+
+	public void testNoFrom() throws Exception {
+		System.out.println( "***** This test ensures that an error is detected ERROR MESSAGES ARE OKAY!  *****" );
+		HqlParser parser = buildHqlParser( "" );
+		parser.statement();
+		assertEquals( "Parser allowed no FROM clause!", 1, parser.getParseErrorHandler().getErrorCount() );
+		System.out.println( "***** END OF ERROR TEST  *****" );
+	}
+
+	public void testHB1042() throws Exception {
+		parse( "select x from fmc_web.pool.Pool x left join x.containers c0 where (upper(x.name) = upper(':') and c0.id = 1)" );
+	}
+
+	public void testKeywordInPath() throws Exception {
+		// The keyword 'order' used as a property name.
+		parse( "from Customer c where c.order.status = 'argh'" );
+		// The keyword 'order' and 'count' used as a property name.
+		parse( "from Customer c where c.order.count > 3" );
+		// The keywords 'where', 'order' and 'count' used as a property name.
+		parse( "select c.where from Customer c where c.order.count > 3" );
+		parse( "from Interval i where i.end <:end" );
+		parse( "from Letter l where l.case = :case" );
+	}
+
+	public void testPathologicalKeywordAsIdentifier() throws Exception {
+		// Super evil badness... a legitimate keyword!
+		parse( "from Order order" );
+		//parse( "from Order order join order.group" );
+		parse( "from X x order by x.group.by.from" );
+		parse( "from Order x order by x.order.group.by.from" );
+		parse( "select order.id from Order order" );
+		parse( "select order from Order order" );
+		parse( "from Order order where order.group.by.from is not null" );
+		parse( "from Order order order by order.group.by.from" );
+		// Okay, now this is getting silly.
+		parse( "from Group as group group by group.by.from" );
+	}
+
+    public void testHHH354() throws Exception {
+        parse( "from Foo f where f.full = 'yep'");
+    }
+
+    public void testWhereAsIdentifier() throws Exception {
+        // 'where' as a package name
+        parse( "from where.Order" );
+    }
+
+	public void testEjbqlKeywordsAsIdentifier() throws Exception {
+		parse( "from org.hibernate.test.Bar bar where bar.object.id = ? and bar.object.class = ?" );
+	}
+
+	public void testConstructorIn() throws Exception {
+		parse( "from org.hibernate.test.Bar bar where (b.x, b.y, b.z) in (select foo, bar, baz from org.hibernate.test.Foo)" );
+	}
+
+    public void testMultiByteCharacters() throws Exception {
+        parse ("from User user where user.name like '%nn\u4e2dnn%'");
+        // Test for HHH-558
+        parse ("from User user where user.\u432d like '%\u4e2d%'");
+        parse ("from \u432d \u432d where \u432d.name like '%fred%'");
+    }
+
+    public void testHHH719() throws Exception {
+        // Some SQLs have function names with package qualifiers.
+        parse("from Foo f order by com.fooco.SpecialFunction(f.id)");
+    }
+
+	public void testHHH1107() throws Exception {
+		parse("from Animal where zoo.address.street = '123 Bogus St.'");
+	}
+
+
+	public void testHHH1247() throws Exception {
+		parse("select distinct user.party from com.itf.iceclaims.domain.party.user.UserImpl user inner join user.party.$RelatedWorkgroups relatedWorkgroups where relatedWorkgroups.workgroup.id = :workgroup and relatedWorkgroups.effectiveTime.start <= :datesnow and relatedWorkgroups.effectiveTime.end > :dateenow ");
+	}
+	public void testLineAndColumnNumber() throws Exception {
+		AST ast = doParse("from Foo f\nwhere f.name = 'fred'",false);
+		// Find some of the nodes and check line and column values.
+		ASTIterator iter = new ASTIterator(ast);
+		boolean foundFoo = false;
+		boolean foundName = false;
+		while (iter.hasNext())
+		{
+			AST n = iter.nextNode();
+			if ("Foo".equals(n.getText()))
+			{
+				if (foundFoo)
+					fail("Already found 'Foo'!");
+				foundFoo = true;
+				Node node = ( Node )n;
+				assertEquals(1,node.getLine());
+				assertEquals(6,node.getColumn());
+			}
+			else if ("name".equals(n.getText()))
+			{
+				if (foundName)
+					fail("Already found 'name'!");
+				foundName = true;
+				Node node = ( Node )n;
+				assertEquals(2,node.getLine());
+				assertEquals(9,node.getColumn());
+			}
+		}
+		assertTrue(foundFoo);
+		assertTrue(foundName);
+	}
+
+
+	private void parse(String input) throws RecognitionException, TokenStreamException {
+		doParse( input, false );
+	}
+
+	private void parseFilter(String input) throws TokenStreamException, RecognitionException {
+		doParse( input, true );
+	}
+
+	public static AST doParse(String input, boolean isFilter) throws RecognitionException, TokenStreamException {
+		System.out.println( "input: ->" + ASTPrinter.escapeMultibyteChars(input) + "<-" );
+		HqlParser parser = buildHqlParser( input );
+		if ( isFilter ) {
+			parser.filterStatement();
+		}
+		else {
+			parser.statement();
+		}
+		AST ast = parser.getAST();
+		show( ast, "AST [" + ast.toStringTree() + "]" );
+		assertEquals( "At least one error occurred during parsing!", 0, parser.getParseErrorHandler().getErrorCount() );
+		return ast;
+	}
+
+	private static HqlParser buildHqlParser(String hql) {
+		return new HqlParser(
+				hql,
+				new HqlParser.Context() {
+					public boolean isEntityName(String name) {
+						return false;
+					}
+
+					public String getImportedName(String name) {
+						return null;
+					}
+
+					public boolean isRegisteredFunctionName(String name) {
+						return false;
+					}
+				}
+		);
+	}
+
+}

Modified: core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties	2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties	2009-01-06 20:11:13 UTC (rev 15747)
@@ -30,4 +30,5 @@
 
 log4j.logger.org.hibernate.test=info
 log4j.logger.org.hibernate.tool.hbm2ddl=debug
-log4j.logger.org.hibernate.sql.ordering.antlr.OrderByFragmentTranslator=trace
\ No newline at end of file
+log4j.logger.org.hibernate.sql.ast.ordering.OrderByFragmentTranslator=trace
+log4j.logger.org.hibernate.hql.ast=trace
\ No newline at end of file




More information about the hibernate-commits mailing list